library(ggplot2)
library(grid)
library(forestploter)
library(tidyverse)
saveto <- "/Volumes/Research Project/IAT_Retest/Plotting/SavedFigs/"
path <- "/Volumes/"
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/UCR/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Estimates/UCR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
Cal1 <-read.csv("IndividualParametersQuadUCR1.csv", header = T)
Cal2 <-read.csv("IndividualParametersQuadUCR2.csv", header = T)
colnames(Cal1)[2:ncol(Cal1)]<-paste(colnames(Cal1[2:ncol(Cal1)]),"T1",sep="_")
colnames(Cal2)[2:ncol(Cal2)]<-paste(colnames(Cal2[2:ncol(Cal2)]),"T2",sep="_")
Q.Cal <- merge(Cal1, Cal2, by = "subject", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/PI/"))
PI1 <- read.csv("IndividualParametersQuadProjectImplicit1.csv")
PI2 <- read.csv("IndividualParametersQuadProjectImplicit2.csv")
colnames(PI1)[2:ncol(PI1)]<-paste(colnames(PI1[2:ncol(PI1)]),"T1",sep="_")
colnames(PI2)[2:ncol(PI2)]<-paste(colnames(PI2[2:ncol(PI2)]),"T2",sep="_")
Q.PI <- merge(PI1, PI2, by = "ID", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Gawronski/"))
Gaw1 <- read.csv("IndividualParametersQuadGawronski1.csv")
Gaw2 <- read.csv("IndividualParametersQuadGawronski2.csv")
colnames(Gaw1)[2:ncol(Gaw1)]<-paste(colnames(Gaw1[2:ncol(Gaw1)]),"T1",sep="_")
colnames(Gaw2)[2:ncol(Gaw2)]<-paste(colnames(Gaw2[2:ncol(Gaw2)]),"T2",sep="_")
Q.Gaw <- merge(Gaw1, Gaw2, by = "code", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Forscher/"))
For1<-read.csv("IndividualParametersQuadForscher1.csv", header = T)
For2<-read.csv("IndividualParametersQuadForscher2.csv", header = T)
colnames(For1)[2:ncol(For1)]<-paste(colnames(For1[2:ncol(For1)]),"T1",sep="_")
colnames(For2)[2:ncol(For2)]<-paste(colnames(For2[2:ncol(For2)]),"T2",sep="_")
Q.For <- merge(For1, For2, by = "subject", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai1/"))
Lai11<-read.csv("IndividualParametersLaiStudy1Quad1.csv", header = T)
Lai12<-read.csv("IndividualParametersLaiStudy1Quad2.csv", header = T)
colnames(Lai11)[2:ncol(Lai11)]<-paste(colnames(Lai11[2:ncol(Lai11)]),"T1",sep="_")
colnames(Lai12)[2:ncol(Lai12)]<-paste(colnames(Lai12[2:ncol(Lai12)]),"T2",sep="_")
Q.Lai1 <- merge(Lai11, Lai12, by = "session_id", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai2/"))
Lai21<-read.csv("IndividualParametersLaiStudy2Quad1.csv", header = T)
Lai22<-read.csv("IndividualParametersLaiStudy2Quad2.csv", header = T)
colnames(Lai21)[2:ncol(Lai21)]<-paste(colnames(Lai21[2:ncol(Lai21)]),"T1",sep="_")
colnames(Lai22)[2:ncol(Lai22)]<-paste(colnames(Lai22[2:ncol(Lai22)]),"T2",sep="_")
Q.Lai2 <- merge(Lai21, Lai22, by = "session_id", all.x = T, all.y = T)
colnames(Q.Cal)[1] <- "subID"
Q.Cal <- cbind(Q.Cal, Study = "Calanchini")
colnames(Q.PI)[1] <- "subID"
Q.PI <- cbind(Q.PI, Study = "PI")
colnames(Q.Gaw)[1] <- "subID"
Q.Gaw <- cbind(Q.Gaw, Study = "Gawronski")
colnames(Q.For)[1] <- "subID"
Q.For <- cbind(Q.For, Study = "Forscher")
colnames(Q.Lai1)[1] <- "subID"
Q.Lai1 <- cbind(Q.Lai1, Study = "Lai 1")
colnames(Q.Lai2)[1] <- "subID"
Q.Lai2 <- cbind(Q.Lai2, Study = "Lai 2")
Quad <- rbind(Q.Cal,Q.PI,Q.Gaw,Q.For,Q.Lai1,Q.Lai2)
Quad$Study[Quad$Study=="PI"]<-"Project Implicit, 2020"
Quad$Study[Quad$Study=="Calanchini"]<-"Wilson & Calanchini, 2022"
Quad$Study[Quad$Study=="Lai 1"]<-"Lai et al., 2016 (Study 1) "
Quad$Study[Quad$Study=="Lai 2"]<-"Lai et al., 2016 (Study 2) "
Quad$Study[Quad$Study=="Gawronski"]<-"Gawronski et al., 2017"
Quad$Study[Quad$Study=="Forscher"]<-"Forscher et al., 2017"
path <- "/Volumes/"
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/UCR/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Estimates/UCR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
Cal1 <-read.csv("IndividualParametersPDUCR1.csv", header = T)
Cal2 <-read.csv("IndividualParametersPDUCR2.csv", header = T)
colnames(Cal1)[2:ncol(Cal1)]<-paste(colnames(Cal1[2:ncol(Cal1)]),"T1",sep="_")
colnames(Cal2)[2:ncol(Cal2)]<-paste(colnames(Cal2[2:ncol(Cal2)]),"T2",sep="_")
P.Cal <- merge(Cal1, Cal2, by = "subject", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/PI/"))
PI1 <- read.csv("IndividualParametersProjectImplicitPD1.csv")
PI2 <- read.csv("IndividualParametersProjectImplicitPD2.csv")
colnames(PI1)[2:ncol(PI1)]<-paste(colnames(PI1[2:ncol(PI1)]),"T1",sep="_")
colnames(PI2)[2:ncol(PI2)]<-paste(colnames(PI2[2:ncol(PI2)]),"T2",sep="_")
P.PI <- merge(PI1, PI2, by = "ID", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Gawronski/"))
Gaw1 <- read.csv("IndividualParametersPDGawronski1.csv")
Gaw2 <- read.csv("IndividualParametersPDGawronski2.csv")
colnames(Gaw1)[2:ncol(Gaw1)]<-paste(colnames(Gaw1[2:ncol(Gaw1)]),"T1",sep="_")
colnames(Gaw2)[2:ncol(Gaw2)]<-paste(colnames(Gaw2[2:ncol(Gaw2)]),"T2",sep="_")
P.Gaw <- merge(Gaw1, Gaw2, by = "code", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Forscher/"))
For1<-read.csv("IndividualParametersForscherPD1.csv", header = T)
For2<-read.csv("IndividualParametersForscherPD2.csv", header = T)
colnames(For1)[2:ncol(For1)]<-paste(colnames(For1[2:ncol(For1)]),"T1",sep="_")
colnames(For2)[2:ncol(For2)]<-paste(colnames(For2[2:ncol(For2)]),"T2",sep="_")
P.For <- merge(For1, For2, by = "subject", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai1/"))
Lai11<-read.csv("IndividualParametersLaiStudy1PD1.csv", header = T)
Lai12<-read.csv("IndividualParametersLaiStudy1PD2.csv", header = T)
colnames(Lai11)[2:ncol(Lai11)]<-paste(colnames(Lai11[2:ncol(Lai11)]),"T1",sep="_")
colnames(Lai12)[2:ncol(Lai12)]<-paste(colnames(Lai12[2:ncol(Lai12)]),"T2",sep="_")
P.Lai1 <- merge(Lai11, Lai12, by = "session_id", all.x = T, all.y = T)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai2/"))
Lai21<-read.csv("IndividualParametersLaiStudy2PD1.csv", header = T)
Lai22<-read.csv("IndividualParametersLaiStudy2PD2.csv", header = T)
colnames(Lai21)[2:ncol(Lai21)]<-paste(colnames(Lai21[2:ncol(Lai21)]),"T1",sep="_")
colnames(Lai22)[2:ncol(Lai22)]<-paste(colnames(Lai22[2:ncol(Lai22)]),"T2",sep="_")
P.Lai2 <- merge(Lai21, Lai22, by = "session_id", all.x = T, all.y = T)
colnames(P.Cal)[1] <- "subID"
P.Cal <- cbind(P.Cal, Study = "Calanchini")
colnames(P.PI)[1] <- "subID"
P.PI <- cbind(P.PI, Study = "PI")
colnames(P.Gaw)[1] <- "subID"
P.Gaw <- cbind(P.Gaw, Study = "Gawronski")
colnames(P.For)[1] <- "subID"
P.For <- cbind(P.For, Study = "Forscher")
colnames(P.Lai1)[1] <- "subID"
P.Lai1 <- cbind(P.Lai1, Study = "Lai 1")
colnames(P.Lai2)[1] <- "subID"
P.Lai2 <- cbind(P.Lai2, Study = "Lai 2")
PD <- rbind(P.Cal,P.PI,P.Gaw,P.For,P.Lai1,P.Lai2)
PD$Study[PD$Study=="PI"]<-"Project Implicit, 2020"
PD$Study[PD$Study=="Calanchini"]<-"Wilson & Calanchini, 2022"
PD$Study[PD$Study=="Lai 1"]<-"Lai et al., 2016 (Study 1) "
PD$Study[PD$Study=="Lai 2"]<-"Lai et al., 2016 (Study 2) "
PD$Study[PD$Study=="Gawronski"]<-"Gawronski et al., 2017"
PD$Study[PD$Study=="Forscher"]<-"Forscher et al., 2017"
Quad Model
Associate Black-Bad
ACbbScatter <- ggplot(Quad, aes(x=ACbb1_T1, y=ACbb1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Association Black-Bad",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
ACbbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACbbScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Associate White-Good
ACwgScatter <- ggplot(Quad, aes(x=ACwg1_T1, y=ACwg1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Association White-Good",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) + theme(legend.title = element_text(size = 9)) +
jtools::theme_apa()
ACwgScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACwgScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Detection
DScatter <- ggplot(Quad, aes(x=D1_T1, y=D1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Detection",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) + theme(legend.title = element_text(size = 9)) +
jtools::theme_apa()
DScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"DScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Overcoming Bias
OBScatter <- ggplot(Quad, aes(x=OB1_T1, y=OB1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Overcoming Bias",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) + theme(legend.title = element_text(size = 9)) +
jtools::theme_apa()
OBScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"OBScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Guessing
GScatter <- ggplot(Quad, aes(x=G1_T1, y=G1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Guessing",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
ggsave(paste0(saveto,"GScatter.jpg"),dpi=600)
Saving 7 x 7 in image
`geom_smooth()` using formula 'y ~ x'
Panel
library(ggpubr)
QuadPanel1 <- ggarrange(ACwgScatter, ACbbScatter, DScatter, OBScatter, GScatter,
ncol = 3, nrow = 2, common.legend = T)
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
QuadPanel1


require(grid) # for the textGrob() function
QuadPanel2 <- ggarrange(ACwgScatter + theme(plot.title = element_text(size=12)) + theme(legend.text = element_text(size = 8)) + rremove("ylab") + rremove("xlab"),
ACbbScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
DScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
OBScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
GScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
ncol = 3, nrow = 2, common.legend = T, labels = NULL, legend = "top",
align = "hv",
font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"))
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
QuadPanel2

annotate_figure(QuadPanel2, left = textGrob("Time 2", rot = 90, vjust = 1, gp = gpar(cex = 1.3)),
bottom = textGrob("Time 1", vjust = -.1, gp = gpar(cex = 1.3)))
ggsave(paste0(saveto,"QuadPanel.jpg"),dpi=600)
Saving 7.29 x 4.51 in image

PD Model
Automatic Black
AbScatter <- ggplot(PD, aes(x=Ab1_T1, y=Ab1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Automatic Black",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
AbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AbScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Associate White
AwScatter <- ggplot(PD, aes(x=Aw1_T1, y=Aw1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Automatic White",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
AwScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AwScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Good
CpScatter <- ggplot(PD, aes(x=Cp1_T1, y=Cp1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Good",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
CpScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CpScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Bad
CuScatter <- ggplot(PD, aes(x=Cu1_T1, y=Cu1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Bad",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
CuScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CuScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control White
CwScatter <- ggplot(PD, aes(x=Cw1_T1, y=Cw1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control White",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
CwScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CwScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control-Black
CbScatter <- ggplot(PD, aes(x=Cb1_T1, y=Cb1_T2, color=Study)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control-Black",
x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
CbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CbScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Panel
library(ggpubr)
PDPanel1 <- ggarrange(AwScatter, AbScatter, CuScatter, CpScatter, CbScatter, CwScatter,
ncol = 3, nrow = 2, common.legend = T)
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
PDPanel1


require(grid) # for the textGrob() function
PDPanel2 <- ggarrange(AwScatter + theme(plot.title = element_text(size=12)) + theme(legend.text = element_text(size = 8)) + rremove("ylab") + rremove("xlab"),
AbScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
CuScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
CpScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
CbScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
CwScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
ncol = 3, nrow = 2, common.legend = T, labels = NULL, legend = "top",
align = "hv",
font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"))
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
PDPanel2 <- annotate_figure(PDPanel2, left = textGrob("Time 2", rot = 90, vjust = 1, gp = gpar(cex = 1.3)),
bottom = textGrob("Time 1", vjust = -.1, gp = gpar(cex = 1.3)))
PDPanel2
ggsave(paste0(saveto,"PDPanel.jpg"),dpi=600)
Saving 7.29 x 4.51 in image

Reliability Meta-Analysis
dt <- read.csv("~/Documents/GitHub/MPT-Reliability/Retest/output/combQuad_Df.csv")[2:6]
dt$Param[dt$Param=="D"]<-"Detection"
dt$Param[dt$Param=="OB"]<-"Overcoming Bias"
dt$Param[dt$Param=="ACbb"]<-"Activation Black-Bad"
dt$Param[dt$Param=="ACwg"]<-"Activation White-Good"
dt$Param[dt$Param=="G"]<-"Guessing"
dt$Param[dt$Param=="PI"]<-"Project Implicit, 2020"
dt$Param[dt$Param=="Calanchini"]<-"Wilson & Calanchini, 2022"
dt$Param[dt$Param=="Lai1"]<-"Lai et al., 2016 (Study 1) "
dt$Param[dt$Param=="Lai2"]<-"Lai et al., 2016 (Study 2) "
dt$Param[dt$Param=="Gawronski"]<-"Gawronski et al., 2017"
dt$Param[dt$Param=="Forscher"]<-"Forscher et al., 2017"
# indent the subgroup if there is a number in the placebo column
dt$Param <- ifelse(dt$type==0,
dt$Param,
paste0(" ", dt$Param))
colnames(dt)[colnames(dt)=="Param"] <- " "
dt$` ` <- paste(rep(" ", 20), collapse = " ")
dt$`ICC (95% CI)` <- ifelse(is.na(dt$ICC), "",
sprintf("%.2f [%.2f, %.2f]",
dt$ICC, dt$CI.LB, dt$CI.UB))
dt<-dt[c(1:4,6:7)]
colnames(dt)[colnames(dt)=="ICC (95% CI)"] <- " "
library(forestploter)
p <- forest(
dt[c(1,5,6)],
est = dt$ICC,
lower = dt$CI.LB,
upper = dt$CI.UB,
ci_column = 2,
ref_line = .4,
xlim = c(-.1, 1),
ticks_at = c(0, .4,.6, .75, 1),
sizes = .1
)
library(grid)
p <- edit_plot(p,
row = seq(from=1,to=nrow(dt),by=7),
gp = gpar(fontface = c("bold","italic")
), col = 1)
studyInds <- setdiff(1:nrow(dt),seq(from=1,to=nrow(dt),by=7))
paramInds <- seq(from=1,to=nrow(dt),by=7)
p <- edit_plot(p, row = studyInds, which = "background",
gp = gpar(fill = "white"))
p <- edit_plot(p, row = paramInds, which = "background",
gp = gpar(fill = "grey"))
png(paste0(saveto,"Quad_TRT.png"), units="in", width=10, height=10, res=300)
plot(p)
dev.off()
null device
1
# ggsave function
ggplot2::ggsave(paste0(saveto,"Quad_TRT.png"),
dpi = 300,
width = 10, height = 10, units = "in", plot=p)
dt <- read.csv("~/Documents/GitHub/MPT-Reliability/Retest/output/combPD_Df.csv")[2:6]
dt$Param[dt$Param=="Ab"]<-"Automatic Black"
dt$Param[dt$Param=="Aw"]<-"Automatic White"
dt$Param[dt$Param=="Cb"]<-"Control Black"
dt$Param[dt$Param=="Cw"]<-"Control White"
dt$Param[dt$Param=="Cu"]<-"Control Bad"
dt$Param[dt$Param=="Cp"]<-"Control Good"
dt$Param[dt$Param=="PI"]<-"Project Implicit, 2020"
dt$Param[dt$Param=="Calanchini"]<-"Wilson & Calanchini, 2022"
dt$Param[dt$Param=="Lai1"]<-"Lai et al., 2016 (Study 1) "
dt$Param[dt$Param=="Lai2"]<-"Lai et al., 2016 (Study 2) "
dt$Param[dt$Param=="Gawronski"]<-"Gawronski et al., 2017"
dt$Param[dt$Param=="Forscher"]<-"Forscher et al., 2017"
# indent the subgroup if there is a number in the placebo column
dt$Param <- ifelse(dt$type==0,
dt$Param,
paste0(" ", dt$Param))
colnames(dt)[colnames(dt)=="Param"] <- " "
colnames(dt)[colnames(dt)=="Param"] <- " "
dt$` ` <- paste(rep(" ", 20), collapse = " ")
dt$`ICC (95% CI)` <- ifelse(is.na(dt$ICC), "",
sprintf("%.2f [%.2f, %.2f]",
dt$ICC, dt$CI.LB, dt$CI.UB))
dt<-dt[c(1:4,6:7)]
colnames(dt)[colnames(dt)=="ICC (95% CI)"] <- " "
library(forestploter)
p <- forest(
dt[c(1,5,6)],
est = dt$ICC,
lower = dt$CI.LB,
upper = dt$CI.UB,
ci_column = 2,
ref_line = .4,
xlim = c(-.1, 1),
ticks_at = c(0, .4,.6, .75, 1),
sizes = .1
)
library(grid)
p <- edit_plot(p,
row = seq(from=1,to=nrow(dt),by=7),
gp = gpar(fontface = c("bold","italic")
), col = 1)
studyInds <- setdiff(1:nrow(dt),seq(from=1,to=nrow(dt),by=7))
paramInds <- seq(from=1,to=nrow(dt),by=7)
p <- edit_plot(p, row = studyInds, which = "background",
gp = gpar(fill = "white"))
p <- edit_plot(p, row = paramInds, which = "background",
gp = gpar(fill = "grey"))
png(paste0(saveto,"PDP_TRT.png"), units="in", width=10, height=12, res=300)
plot(p)
dev.off()
null device
1
# ggsave function
ggplot2::ggsave(paste0(saveto,"PDP_TRT.png"),
dpi = 300,
width = 10, height = 12, units = "in", plot=p)
Recovery
setwd(paste0("/Volumes/Research Project/IAT_Retest/Recovery/RecoveredParams/PD/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Recovery/RecoveredParams/PD inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
times<-c("Time1","Time2")
allrecovs <- as.data.frame(matrix(ncol=14,nrow=0))
PDdirs <- list.dirs(path = ".", full.names = TRUE, recursive = TRUE)[-1]
for(d in PDdirs){
for(ti in times){
curFiles <- list.files(path=d,pattern="\\.csv$")
id<-grep(ti,curFiles)
output<-read.csv(paste0(d,"/",curFiles[id]))
name<-gsub("./","",d)
name<-gsub(" ","",name)
if(ti=="Time1"){
#colnames(output) <- paste(colnames(output),"T1",sep="_")
output$time <- "T1"
}else if(ti=="Time2"){
#colnames(output) <- paste(colnames(output),"T2",sep="_")
output$time <- "T2"
}
assign(paste0(name,".PD.Recov.",ti),output)
}
df <- rbind(get(paste0(name,".PD.Recov.Time1")),get(paste0(name,".PD.Recov.Time2")))
assign(paste0(name,".PD.Recov"),df)
allrecovs <- rbind(allrecovs,cbind(df,Study=name))
}
allrecovs$Study <- gsub("Lai1", "Lai 1", allrecovs$Study)
allrecovs$Study <- gsub("Lai2", "Lai 2", allrecovs$Study)
PD.recovs <- allrecovs
PD.recovs <- dplyr::rename(PD.recovs, subID=X)
tapply(PD.recovs$Ab1, PD.recovs$Study, function(x) length(x))
Calanchini Forscher Gawronski Lai 1 Lai 2 PI
210 64 232 160 926 2480
path <- "/Volumes/"
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/UCR/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Estimates/UCR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
Cal1 <-read.csv("IndividualParametersPDUCR1.csv", header = T)
Cal2 <-read.csv("IndividualParametersPDUCR2.csv", header = T)
Cal1$time <- "T1"
Cal2$time <- "T2"
Cal1$subID <- 1:nrow(Cal1)
Cal2$subID <- 1:nrow(Cal2)
P.Cal <- rbind(Cal1, Cal2)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/PI/"))
PI1 <- read.csv("IndividualParametersProjectImplicitPD1.csv")
PI2 <- read.csv("IndividualParametersProjectImplicitPD2.csv")
PI1$time <- "T1"
PI2$time <- "T2"
PI1$subID <- 1:nrow(PI1)
PI2$subID <- 1:nrow(PI2)
P.PI <- rbind(PI1, PI2)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Gawronski/"))
Gaw1 <- read.csv("IndividualParametersPDGawronski1.csv")
Gaw2 <- read.csv("IndividualParametersPDGawronski2.csv")
Gaw1$time <- "T1"
Gaw2$time <- "T2"
Gaw1$subID <- 1:nrow(Gaw1)
Gaw2$subID <- 1:nrow(Gaw2)
P.Gaw <- rbind(Gaw1, Gaw2)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Forscher/"))
For1<-read.csv("IndividualParametersForscherPD1.csv", header = T)
For2<-read.csv("IndividualParametersForscherPD2.csv", header = T)
For1$time <- "T1"
For2$time <- "T2"
For1$subID <- 1:nrow(For1)
For2$subID <- 1:nrow(For2)
P.For <- rbind(For1, For2)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai1/"))
Lai11<-read.csv("IndividualParametersLaiStudy1PD1.csv", header = T)
Lai12<-read.csv("IndividualParametersLaiStudy1PD2.csv", header = T)
Lai11$time <- "T1"
Lai12$time <- "T2"
Lai11$subID <- 1:nrow(Lai11)
Lai12$subID <- 1:nrow(Lai12)
P.Lai1 <- rbind(Lai11, Lai12)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai2/"))
Lai21<-read.csv("IndividualParametersLaiStudy2PD1.csv", header = T)
Lai22<-read.csv("IndividualParametersLaiStudy2PD2.csv", header = T)
Lai21$time <- "T1"
Lai22$time <- "T2"
Lai21$subID <- 1:nrow(Lai21)
Lai22$subID <- 1:nrow(Lai22)
P.Lai2 <- rbind(Lai21,Lai22)
colnames(P.Cal)[1] <- "subID"
P.Cal <- cbind(P.Cal, Study = "Calanchini")
colnames(P.PI)[1] <- "subID"
P.PI <- cbind(P.PI, Study = "PI")
colnames(P.Gaw)[1] <- "subID"
P.Gaw <- cbind(P.Gaw, Study = "Gawronski")
colnames(P.For)[1] <- "subID"
P.For <- cbind(P.For, Study = "Forscher")
colnames(P.Lai1)[1] <- "subID"
P.Lai1 <- cbind(P.Lai1, Study = "Lai 1")
colnames(P.Lai2)[1] <- "subID"
P.Lai2 <- cbind(P.Lai2, Study = "Lai 2")
PD.orig <- rbind(P.Cal,P.PI,P.Gaw,P.For,P.Lai1,P.Lai2)
PD.orig[1] <- NULL
colnames(PD.recovs)[2: (ncol(PD.recovs)-2) ] <- paste(colnames(PD.recovs)[2: (ncol(PD.recovs)-2) ],"R",sep="_")
colnames(PD.orig)[1: (ncol(PD.orig)-3) ] <- paste(colnames(PD.orig)[1: (ncol(PD.orig)-3) ],"O",sep="_")
PD.orig <- PD.orig[order(PD.orig$Study, PD.orig$time),]
PD.recovs <- PD.recovs[order(PD.recovs$Study, PD.recovs$time),]
#PD.orig.recovs <- cbind(PD.orig,PD.recovs)
PD.orig.recovs <- merge(PD.orig, PD.recovs, by = c("subID","Study","time"))
PD.orig.recovs$Study[PD.orig.recovs$Study=="PI"]<-"Project Implicit, 2020"
PD.orig.recovs$Study[PD.orig.recovs$Study=="Calanchini"]<-"Wilson & Calanchini, 2022"
PD.orig.recovs$Study[PD.orig.recovs$Study=="Lai 1"]<-"Lai et al., 2016 (Study 1) "
PD.orig.recovs$Study[PD.orig.recovs$Study=="Lai 2"]<-"Lai et al., 2016 (Study 2) "
PD.orig.recovs$Study[PD.orig.recovs$Study=="Gawronski"]<-"Gawronski et al., 2017"
PD.orig.recovs$Study[PD.orig.recovs$Study=="Forscher"]<-"Forscher et al., 2017"
Recovery
PD Model
Automatic Black
AbScatter <- ggplot(PD.orig.recovs, aes(x=Ab1_O, y=Ab1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Automatic Black",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
AbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AbScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Automatic White
AwScatter <- ggplot(PD.orig.recovs, aes(x=Aw1_O, y=Aw1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Automatic White",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
AwScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AwScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Good
CpScatter <- ggplot(PD.orig.recovs, aes(x=Cp1_O, y=Cp1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Good",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
CpScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CpScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Bad
CuScatter <- ggplot(PD.orig.recovs, aes(x=Cu1_O, y=Cu1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Bad",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
CuScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CuScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control White
CwScatter <- ggplot(PD.orig.recovs, aes(x=Cw1_O, y=Cw1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control White",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
CwScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CwScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control-Black
CbScatter <- ggplot(PD.orig.recovs, aes(x=Cb1_O, y=Cb1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Black",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
CbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CbScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Panel
library(ggpubr)
PDPanel1 <- ggarrange(AwScatter, AbScatter, CuScatter, CpScatter, CbScatter, CwScatter,
ncol = 3, nrow = 2, common.legend = T)
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
PDPanel1


require(grid) # for the textGrob() function
PDPanel2 <- ggarrange(AwScatter + theme(plot.title = element_text(size=12)) + theme(legend.text = element_text(size = 8)) + rremove("ylab") + rremove("xlab"),
AbScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
CuScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
CpScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
CbScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
CwScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
ncol = 3, nrow = 2, common.legend = T, labels = NULL, legend = c("top","bottom"),
align = "hv",
font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"))
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
PDPanel2 <- annotate_figure(PDPanel2, left = textGrob("Recovered", rot = 90, vjust = 1, gp = gpar(cex = 1.3)),
bottom = textGrob("Original", vjust = -.1, gp = gpar(cex = 1.3)))
PDPanel2
ggsave(paste0(saveto,"PDPanelREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image

Quad Model
Recovery
setwd(paste0("/Volumes/Research Project/IAT_Retest/Recovery/RecoveredParams/Quad/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Recovery/RecoveredParams/Quad inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
times<-c("Time1","Time2")
allrecovs <- as.data.frame(matrix(ncol=14,nrow=0))
Quaddirs <- list.dirs(path = ".", full.names = TRUE, recursive = TRUE)[-1]
for(d in Quaddirs){
for(ti in times){
curFiles <- list.files(path=d,pattern="\\.csv$")
id<-grep(ti,curFiles)
output<-read.csv(paste0(d,"/",curFiles[id]))
name<-gsub("./","",d)
name<-gsub(" ","",name)
if(ti=="Time1"){
#colnames(output) <- paste(colnames(output),"T1",sep="_")
output$time <- "T1"
}else if(ti=="Time2"){
#colnames(output) <- paste(colnames(output),"T2",sep="_")
output$time <- "T2"
}
assign(paste0(name,".Quad.Recov.",ti),output)
}
df <- rbind(get(paste0(name,".Quad.Recov.Time1")),get(paste0(name,".Quad.Recov.Time2")))
assign(paste0(name,".Quad.Recov"),df)
allrecovs <- rbind(allrecovs,cbind(df,Study=name))
}
allrecovs$Study <- gsub("Lai1", "Lai 1", allrecovs$Study)
allrecovs$Study <- gsub("Lai2", "Lai 2", allrecovs$Study)
Quad.recovs <- allrecovs
Quad.recovs <- dplyr::rename(Quad.recovs, subID=X)
tapply(Quad.recovs$ACbb1, Quad.recovs$Study, function(x) length(x))
Calanchini Forscher Gawronski Lai 1 Lai 2 PI
210 64 232 160 926 2480
path <- "/Volumes/"
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/UCR/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Estimates/UCR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
Cal1 <-read.csv("IndividualParametersQuadUCR1.csv", header = T)
Cal2 <-read.csv("IndividualParametersQuadUCR2.csv", header = T)
Cal1$time <- "T1"
Cal2$time <- "T2"
Cal1$subID <- 1:nrow(Cal1)
Cal2$subID <- 1:nrow(Cal2)
P.Cal <- rbind(Cal1, Cal2)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/PI/"))
PI1 <- read.csv("IndividualParametersQuadProjectImplicit1.csv")
PI2 <- read.csv("IndividualParametersQuadProjectImplicit2.csv")
PI1$time <- "T1"
PI2$time <- "T2"
PI1$subID <- 1:nrow(PI1)
PI2$subID <- 1:nrow(PI2)
P.PI <- rbind(PI1, PI2)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Gawronski/"))
Gaw1 <- read.csv("IndividualParametersQuadGawronski1.csv")
Gaw2 <- read.csv("IndividualParametersQuadGawronski2.csv")
Gaw1$time <- "T1"
Gaw2$time <- "T2"
Gaw1$subID <- 1:nrow(Gaw1)
Gaw2$subID <- 1:nrow(Gaw2)
P.Gaw <- rbind(Gaw1, Gaw2)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Forscher/"))
For1<-read.csv("IndividualParametersQuadForscher1.csv", header = T)
For2<-read.csv("IndividualParametersQuadForscher2.csv", header = T)
For1$time <- "T1"
For2$time <- "T2"
For1$subID <- 1:nrow(For1)
For2$subID <- 1:nrow(For2)
P.For <- rbind(For1, For2)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai1/"))
Lai11<-read.csv("IndividualParametersLaiStudy1Quad1.csv", header = T)
Lai12<-read.csv("IndividualParametersLaiStudy1Quad2.csv", header = T)
Lai11$time <- "T1"
Lai12$time <- "T2"
Lai11$subID <- 1:nrow(Lai11)
Lai12$subID <- 1:nrow(Lai12)
P.Lai1 <- rbind(Lai11, Lai12)
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai2/"))
Lai21<-read.csv("IndividualParametersLaiStudy2Quad1.csv", header = T)
Lai22<-read.csv("IndividualParametersLaiStudy2Quad2.csv", header = T)
Lai21$time <- "T1"
Lai22$time <- "T2"
Lai21$subID <- 1:nrow(Lai21)
Lai22$subID <- 1:nrow(Lai22)
P.Lai2 <- rbind(Lai21,Lai22)
colnames(P.Cal)[1] <- "subID"
P.Cal <- cbind(P.Cal, Study = "Calanchini")
colnames(P.PI)[1] <- "subID"
P.PI <- cbind(P.PI, Study = "PI")
colnames(P.Gaw)[1] <- "subID"
P.Gaw <- cbind(P.Gaw, Study = "Gawronski")
colnames(P.For)[1] <- "subID"
P.For <- cbind(P.For, Study = "Forscher")
colnames(P.Lai1)[1] <- "subID"
P.Lai1 <- cbind(P.Lai1, Study = "Lai 1")
colnames(P.Lai2)[1] <- "subID"
P.Lai2 <- cbind(P.Lai2, Study = "Lai 2")
Quad.orig <- rbind(P.Cal,P.PI,P.Gaw,P.For,P.Lai1,P.Lai2)
Quad.orig[1] <- NULL
colnames(Quad.recovs)[2: (ncol(Quad.recovs)-2) ] <- paste(colnames(Quad.recovs)[2: (ncol(Quad.recovs)-2) ],"R",sep="_")
colnames(Quad.orig)[1: (ncol(Quad.orig)-3) ] <- paste(colnames(Quad.orig)[1: (ncol(Quad.orig)-3) ],"O",sep="_")
Quad.orig <- Quad.orig[order(Quad.orig$Study, Quad.orig$time),]
Quad.recovs <- Quad.recovs[order(Quad.recovs$Study, Quad.recovs$time),]
#Quad.orig.recovs <- cbind(Quad.orig,Quad.recovs)
Quad.orig.recovs <- merge(Quad.orig, Quad.recovs, by = c("subID","Study","time"))
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="PI"]<-"Project Implicit, 2020"
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Calanchini"]<-"Wilson & Calanchini, 2022"
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Lai 1"]<-"Lai et al., 2016 (Study 1) "
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Lai 2"]<-"Lai et al., 2016 (Study 2) "
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Gawronski"]<-"Gawronski et al., 2017"
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Forscher"]<-"Forscher et al., 2017"
Quad Model
Associate Black-Bad
ACbbScatter <- ggplot(Quad.orig.recovs, aes(x=ACbb1_O, y=ACbb1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Association Black-Bad",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
ACbbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACbbScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Associate White-Good
ACwgScatter <- ggplot(Quad.orig.recovs, aes(x=ACwg1_O, y=ACwg1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Association White-Good",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
ACwgScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACwgScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Detection
DScatter <- ggplot(Quad.orig.recovs, aes(x=D1_O, y=D1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Detection",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
DScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"DScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Overcoming Bias
OBScatter <- ggplot(Quad.orig.recovs, aes(x=OB1_O, y=OB1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Overcoming Bias",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
OBScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"OBScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Guessing
GScatter <- ggplot(Quad.orig.recovs, aes(x=G1_O, y=G1_R, color=Study, shape=time)) +
geom_point(alpha = .2)+
geom_smooth(method=lm, se=TRUE, linetype="dashed",
color="grey") + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Guessing",
x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
jtools::theme_apa()
GScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"GScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Panel
library(ggpubr)
QuadPanel1 <- ggarrange(ACwgScatter, ACbbScatter, DScatter, OBScatter, GScatter,
ncol = 3, nrow = 2, common.legend = T)
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
QuadPanel1


require(grid) # for the textGrob() function
QuadPanel2 <- ggarrange(ACwgScatter + theme(plot.title = element_text(size=12)) + theme(legend.text = element_text(size = 8)) + rremove("ylab") + rremove("xlab"),
ACbbScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
DScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
OBScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
GScatter + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
ncol = 3, nrow = 2, common.legend = T, labels = NULL, legend = "top",
align = "hv",
font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"))
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
QuadPanel2

annotate_figure(QuadPanel2, left = textGrob("Recovered", rot = 90, vjust = 1, gp = gpar(cex = 1.3)),
bottom = textGrob("Original", vjust = -.1, gp = gpar(cex = 1.3)))
ggsave(paste0(saveto,"QuadPanelREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image

Recovery Meta-Analysis
Quad
dt <- read.csv("~/Documents/GitHub/MPT-Reliability/Recovery/output/combQuad_Recovery_Df.csv")[2:7]
dt$id <- unlist(lapply(1:5, function(x) rep(x,times=13)))
dt$Param[dt$Param=="D"]<-"Detection"
dt$Param[dt$Param=="OB"]<-"Overcoming Bias"
dt$Param[dt$Param=="ACbb"]<-"Activation Black-Bad"
dt$Param[dt$Param=="ACwg"]<-"Activation White-Good"
dt$Param[dt$Param=="G"]<-"Guessing"
dt$Param[dt$Param=="PI"]<-"Project Implicit, 2020"
dt$Param[dt$Param=="Calanchini"]<-"Wilson & Calanchini, 2022"
dt$Param[dt$Param=="Lai1"]<-"Lai et al., 2016 (Study 1) "
dt$Param[dt$Param=="Lai2"]<-"Lai et al., 2016 (Study 2) "
dt$Param[dt$Param=="Gawronski"]<-"Gawronski et al., 2017"
dt$Param[dt$Param=="Forscher"]<-"Forscher et al., 2017"
# indent the subgroup if there is a number in the placebo column
dt$Param <- ifelse(dt$type==0,
dt$Param,
paste0(" ", dt$Param))
dt$` ` <- paste(rep(" ", 20), collapse = " ")
dt$`Recovery (95% CI)` <- ifelse(is.na(dt$Recov), "",
sprintf("%.2f [%.2f, %.2f]",
dt$Recov, dt$CI.LB, dt$CI.UB))
dt2 <- pivot_wider(dt, id_cols = c("Param","id"), names_from = c(Time), values_from = c(Recov,CI.LB,CI.UB,`Recovery (95% CI)`) )
dt2$`Recovery [95% CI]` <- ifelse(!is.na(dt2$`Recovery (95% CI)_Meta`), paste0(" ",dt2$`Recovery (95% CI)_Meta`), paste0("T1 :", paste0(dt2$`Recovery (95% CI)_Time1`), " ; ", "T2: ", paste0(dt2$`Recovery (95% CI)_Time2`)))
dt2$` ` <- paste(rep(" ", 20), collapse = " ")
dt3<-dt2 %>% select(Param,Recov_Meta:11,15,16)
colnames(dt3)[colnames(dt3)=="Param"] <- " "
colnames(dt3)[colnames(dt3)=="Recovery [95% CI]"] <- " "
dt3$size_Meta <- ifelse(is.na(dt3$Recov_Meta), NA, 1.2)
dt3$size_T1 <- ifelse(is.na(dt3$Recov_Time1), NA, .6)
dt3$size_T2 <- ifelse(is.na(dt3$Recov_Time2), NA, .6)
# Set-up theme
tm <- forest_theme(
ci_pch = c(15, 16, 17),
ci_col = c("black","red","blue"),
ci_lty = c( "solid", "dashed", "dotted"),
# footnote_col = "blue",
legend_name = " ",
legend_position = "bottom",
legend_value = c("Meta-Analsis ", "Time 1 ", "Time 2 "))
library(forestploter)
p <- forest(
dt3[c(1,12,11)],
est = list(dt3$Recov_Meta, dt3$Recov_Time1, dt3$Recov_Time2),
lower = list(dt3$CI.LB_Meta, dt3$CI.LB_Time1, dt3$CI.LB_Time2),
upper = list(dt3$CI.UB_Meta, dt3$CI.UB_Time1, dt3$CI.UB_Time2),
ci_column = 2,
ref_line = .7,
xlim = c(-.1, 1),
ticks_at = c(0, 2, .5, .7, 1),
sizes = list(dt3$size_Meta, dt3$size_T1, dt3$size_T2),
theme = tm
)
Warning in check_errors(data = data, est = est, lower = lower, upper = upper, :
ticks_at is outside the xlim.
plot(p)


library(grid)
p <- edit_plot(p,
row = seq(from=1,to=nrow(dt3),by=7),
gp = gpar(fontface = c("bold","italic")
), col = 1)
studyInds <- setdiff(1:nrow(dt3),seq(from=1,to=nrow(dt3),by=7))
paramInds <- seq(from=1,to=nrow(dt),by=7)
p <- edit_plot(p, row = studyInds, which = "background",
gp = gpar(fill = "white"))
p <- edit_plot(p, row = paramInds, which = "background",
gp = gpar(fill = "grey"))
png("~/Desktop/Quad_RecovForest.png", units="in", width=10, height=15, res=300)
plot(p)
dev.off()
null device
1
# ggsave function
ggplot2::ggsave(paste0(saveto,"Quad_RecovForest.png"),
dpi = 300,
width = 10, height = 15, units = "in", plot=p)
dt <- read.csv("~/Documents/GitHub/MPT-Reliability/Recovery/output/combPD_Recovery_Df.csv")[2:7]
dt$id <- unlist(lapply(1:6, function(x) rep(x,times=13)))
dt$Param[dt$Param=="Ab"]<-"Automatic Black"
dt$Param[dt$Param=="Aw"]<-"Automatic White"
dt$Param[dt$Param=="Cb"]<-"Control Black"
dt$Param[dt$Param=="Cw"]<-"Control White"
dt$Param[dt$Param=="Cu"]<-"Control Bad"
dt$Param[dt$Param=="Cp"]<-"Control Good"
dt$Param[dt$Param=="PI"]<-"Project Implicit, 2020"
dt$Param[dt$Param=="Calanchini"]<-"Wilson & Calanchini, 2022"
dt$Param[dt$Param=="Lai1"]<-"Lai et al., 2016 (Study 1) "
dt$Param[dt$Param=="Lai2"]<-"Lai et al., 2016 (Study 2) "
dt$Param[dt$Param=="Gawronski"]<-"Gawronski et al., 2017"
dt$Param[dt$Param=="Forscher"]<-"Forscher et al., 2017"
# indent the subgroup if there is a number in the placebo column
dt$Param <- ifelse(dt$type==0,
dt$Param,
paste0(" ", dt$Param))
dt$` ` <- paste(rep(" ", 20), collapse = " ")
dt$`Recovery (95% CI)` <- ifelse(is.na(dt$Recov), "",
sprintf("%.2f [%.2f, %.2f]",
dt$Recov, dt$CI.LB, dt$CI.UB))
dt2 <- pivot_wider(dt, id_cols = c("Param","id"), names_from = c(Time), values_from = c(Recov,CI.LB,CI.UB,`Recovery (95% CI)`) )
dt2$`Recovery [95% CI]` <- ifelse(!is.na(dt2$`Recovery (95% CI)_Meta`), paste0(" ",dt2$`Recovery (95% CI)_Meta`), paste0("T1 :", paste0(dt2$`Recovery (95% CI)_Time1`), " ; ", "T2: ", paste0(dt2$`Recovery (95% CI)_Time2`)))
dt2$` ` <- paste(rep(" ", 20), collapse = " ")
dt3<-dt2 %>% select(Param,Recov_Meta:11,15,16)
colnames(dt3)[colnames(dt3)=="Param"] <- " "
colnames(dt3)[colnames(dt3)=="Recovery [95% CI]"] <- " "
dt3$size_Meta <- ifelse(is.na(dt3$Recov_Meta), NA, 1.2)
dt3$size_T1 <- ifelse(is.na(dt3$Recov_Time1), NA, .6)
dt3$size_T2 <- ifelse(is.na(dt3$Recov_Time2), NA, .6)
# Set-up theme
tm <- forest_theme(
ci_pch = c(15, 16, 17),
ci_col = c("black","red","blue"),
ci_lty = c( "solid", "dashed", "dotted"),
# footnote_col = "blue",
legend_name = " ",
legend_position = "bottom",
legend_value = c("Meta-Analsis ", "Time 1 ", "Time 2 "))
library(forestploter)
p <- forest(
dt3[c(1,12,11)],
est = list(dt3$Recov_Meta, dt3$Recov_Time1, dt3$Recov_Time2),
lower = list(dt3$CI.LB_Meta, dt3$CI.LB_Time1, dt3$CI.LB_Time2),
upper = list(dt3$CI.UB_Meta, dt3$CI.UB_Time1, dt3$CI.UB_Time2),
ci_column = 2,
ref_line = .7,
xlim = c(-.1, 1),
ticks_at = c(0, 2, .5, .7, 1),
sizes = list(dt3$size_Meta, dt3$size_T1, dt3$size_T2),
theme = tm
)
Warning in check_errors(data = data, est = est, lower = lower, upper = upper, :
ticks_at is outside the xlim.
plot(p)


library(grid)
p <- edit_plot(p,
row = seq(from=1,to=nrow(dt3),by=7),
gp = gpar(fontface = c("bold","italic")
), col = 1)
studyInds <- setdiff(1:nrow(dt3),seq(from=1,to=nrow(dt3),by=7))
paramInds <- seq(from=1,to=nrow(dt),by=7)
p <- edit_plot(p, row = studyInds, which = "background",
gp = gpar(fill = "white"))
p <- edit_plot(p, row = paramInds, which = "background",
gp = gpar(fill = "grey"))
png("~/Desktop/PD_RecovForest.png", units="in", width=10, height=18, res=300)
plot(p)
dev.off()
null device
1
# ggsave function
ggplot2::ggsave(paste0(saveto,"PD_RecovForest.png"),
dpi = 300,
width = 10, height = 18, units = "in", plot=p)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkKQpsaWJyYXJ5KGZvcmVzdHBsb3RlcikKbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKYGBge3J9CnNhdmV0byA8LSAiL1ZvbHVtZXMvUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L1Bsb3R0aW5nL1NhdmVkRmlncy8iCmBgYAoKCgpgYGB7cn0KcGF0aCA8LSAiL1ZvbHVtZXMvIgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9VQ1IvIikpCkNhbDEgPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkVUNSMS5jc3YiLCBoZWFkZXIgPSBUKQpDYWwyIDwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZFVDUjIuY3N2IiwgaGVhZGVyID0gVCkKCmNvbG5hbWVzKENhbDEpWzI6bmNvbChDYWwxKV08LXBhc3RlKGNvbG5hbWVzKENhbDFbMjpuY29sKENhbDEpXSksIlQxIixzZXA9Il8iKQpjb2xuYW1lcyhDYWwyKVsyOm5jb2woQ2FsMildPC1wYXN0ZShjb2xuYW1lcyhDYWwyWzI6bmNvbChDYWwyKV0pLCJUMiIsc2VwPSJfIikKClEuQ2FsIDwtIG1lcmdlKENhbDEsIENhbDIsIGJ5ID0gInN1YmplY3QiLCBhbGwueCA9IFQsIGFsbC55ID0gVCkKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL1BJLyIpKQpQSTEgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZFByb2plY3RJbXBsaWNpdDEuY3N2IikKUEkyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRQcm9qZWN0SW1wbGljaXQyLmNzdiIpCgpjb2xuYW1lcyhQSTEpWzI6bmNvbChQSTEpXTwtcGFzdGUoY29sbmFtZXMoUEkxWzI6bmNvbChQSTEpXSksIlQxIixzZXA9Il8iKQpjb2xuYW1lcyhQSTIpWzI6bmNvbChQSTIpXTwtcGFzdGUoY29sbmFtZXMoUEkyWzI6bmNvbChQSTIpXSksIlQyIixzZXA9Il8iKQoKUS5QSSA8LSBtZXJnZShQSTEsIFBJMiwgYnkgPSAiSUQiLCBhbGwueCA9IFQsIGFsbC55ID0gVCkKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0dhd3JvbnNraS8iKSkKR2F3MSA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkR2F3cm9uc2tpMS5jc3YiKQpHYXcyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRHYXdyb25za2kyLmNzdiIpCgpjb2xuYW1lcyhHYXcxKVsyOm5jb2woR2F3MSldPC1wYXN0ZShjb2xuYW1lcyhHYXcxWzI6bmNvbChHYXcxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoR2F3MilbMjpuY29sKEdhdzIpXTwtcGFzdGUoY29sbmFtZXMoR2F3MlsyOm5jb2woR2F3MildKSwiVDIiLHNlcD0iXyIpCgpRLkdhdyA8LSBtZXJnZShHYXcxLCBHYXcyLCBieSA9ICJjb2RlIiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9Gb3JzY2hlci8iKSkKRm9yMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZEZvcnNjaGVyMS5jc3YiLCBoZWFkZXIgPSBUKQpGb3IyPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkRm9yc2NoZXIyLmNzdiIsIGhlYWRlciA9IFQpCgpjb2xuYW1lcyhGb3IxKVsyOm5jb2woRm9yMSldPC1wYXN0ZShjb2xuYW1lcyhGb3IxWzI6bmNvbChGb3IxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoRm9yMilbMjpuY29sKEZvcjIpXTwtcGFzdGUoY29sbmFtZXMoRm9yMlsyOm5jb2woRm9yMildKSwiVDIiLHNlcD0iXyIpCgpRLkZvciA8LSBtZXJnZShGb3IxLCBGb3IyLCBieSA9ICJzdWJqZWN0IiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9MYWkxLyIpKQpMYWkxMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkxUXVhZDEuY3N2IiwgaGVhZGVyID0gVCkKTGFpMTI8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0xhaVN0dWR5MVF1YWQyLmNzdiIsIGhlYWRlciA9IFQpCgpjb2xuYW1lcyhMYWkxMSlbMjpuY29sKExhaTExKV08LXBhc3RlKGNvbG5hbWVzKExhaTExWzI6bmNvbChMYWkxMSldKSwiVDEiLHNlcD0iXyIpCmNvbG5hbWVzKExhaTEyKVsyOm5jb2woTGFpMTIpXTwtcGFzdGUoY29sbmFtZXMoTGFpMTJbMjpuY29sKExhaTEyKV0pLCJUMiIsc2VwPSJfIikKClEuTGFpMSA8LSBtZXJnZShMYWkxMSwgTGFpMTIsIGJ5ID0gInNlc3Npb25faWQiLCBhbGwueCA9IFQsIGFsbC55ID0gVCkKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0xhaTIvIikpCkxhaTIxPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTJRdWFkMS5jc3YiLCBoZWFkZXIgPSBUKQpMYWkyMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkyUXVhZDIuY3N2IiwgaGVhZGVyID0gVCkKCmNvbG5hbWVzKExhaTIxKVsyOm5jb2woTGFpMjEpXTwtcGFzdGUoY29sbmFtZXMoTGFpMjFbMjpuY29sKExhaTIxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoTGFpMjIpWzI6bmNvbChMYWkyMildPC1wYXN0ZShjb2xuYW1lcyhMYWkyMlsyOm5jb2woTGFpMjIpXSksIlQyIixzZXA9Il8iKQoKUS5MYWkyIDwtIG1lcmdlKExhaTIxLCBMYWkyMiwgYnkgPSAic2Vzc2lvbl9pZCIsIGFsbC54ID0gVCwgYWxsLnkgPSBUKQoKY29sbmFtZXMoUS5DYWwpWzFdIDwtICJzdWJJRCIKUS5DYWwgPC0gY2JpbmQoUS5DYWwsIFN0dWR5ID0gIkNhbGFuY2hpbmkiKQpjb2xuYW1lcyhRLlBJKVsxXSA8LSAic3ViSUQiClEuUEkgPC0gY2JpbmQoUS5QSSwgU3R1ZHkgPSAiUEkiKQpjb2xuYW1lcyhRLkdhdylbMV0gPC0gInN1YklEIgpRLkdhdyA8LSBjYmluZChRLkdhdywgU3R1ZHkgPSAiR2F3cm9uc2tpIikKY29sbmFtZXMoUS5Gb3IpWzFdIDwtICJzdWJJRCIKUS5Gb3IgPC0gY2JpbmQoUS5Gb3IsIFN0dWR5ID0gIkZvcnNjaGVyIikKY29sbmFtZXMoUS5MYWkxKVsxXSA8LSAic3ViSUQiClEuTGFpMSA8LSBjYmluZChRLkxhaTEsIFN0dWR5ID0gIkxhaSAxIikKY29sbmFtZXMoUS5MYWkyKVsxXSA8LSAic3ViSUQiClEuTGFpMiA8LSBjYmluZChRLkxhaTIsIFN0dWR5ID0gIkxhaSAyIikKClF1YWQgPC0gcmJpbmQoUS5DYWwsUS5QSSxRLkdhdyxRLkZvcixRLkxhaTEsUS5MYWkyKQoKClF1YWQkU3R1ZHlbUXVhZCRTdHVkeT09IlBJIl08LSJQcm9qZWN0IEltcGxpY2l0LCAyMDIwIgpRdWFkJFN0dWR5W1F1YWQkU3R1ZHk9PSJDYWxhbmNoaW5pIl08LSJXaWxzb24gJiBDYWxhbmNoaW5pLCAyMDIyIgpRdWFkJFN0dWR5W1F1YWQkU3R1ZHk9PSJMYWkgMSJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMSkgICIKUXVhZCRTdHVkeVtRdWFkJFN0dWR5PT0iTGFpIDIiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDIpICAiClF1YWQkU3R1ZHlbUXVhZCRTdHVkeT09Ikdhd3JvbnNraSJdPC0iR2F3cm9uc2tpIGV0IGFsLiwgMjAxNyIKUXVhZCRTdHVkeVtRdWFkJFN0dWR5PT0iRm9yc2NoZXIiXTwtIkZvcnNjaGVyIGV0IGFsLiwgMjAxNyIKYGBgCgpgYGB7cn0KcGF0aCA8LSAiL1ZvbHVtZXMvIgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9VQ1IvIikpCkNhbDEgPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQRFVDUjEuY3N2IiwgaGVhZGVyID0gVCkKQ2FsMiA8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1BEVUNSMi5jc3YiLCBoZWFkZXIgPSBUKQoKY29sbmFtZXMoQ2FsMSlbMjpuY29sKENhbDEpXTwtcGFzdGUoY29sbmFtZXMoQ2FsMVsyOm5jb2woQ2FsMSldKSwiVDEiLHNlcD0iXyIpCmNvbG5hbWVzKENhbDIpWzI6bmNvbChDYWwyKV08LXBhc3RlKGNvbG5hbWVzKENhbDJbMjpuY29sKENhbDIpXSksIlQyIixzZXA9Il8iKQoKUC5DYWwgPC0gbWVyZ2UoQ2FsMSwgQ2FsMiwgYnkgPSAic3ViamVjdCIsIGFsbC54ID0gVCwgYWxsLnkgPSBUKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvUEkvIikpClBJMSA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQcm9qZWN0SW1wbGljaXRQRDEuY3N2IikKUEkyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1Byb2plY3RJbXBsaWNpdFBEMi5jc3YiKQoKY29sbmFtZXMoUEkxKVsyOm5jb2woUEkxKV08LXBhc3RlKGNvbG5hbWVzKFBJMVsyOm5jb2woUEkxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoUEkyKVsyOm5jb2woUEkyKV08LXBhc3RlKGNvbG5hbWVzKFBJMlsyOm5jb2woUEkyKV0pLCJUMiIsc2VwPSJfIikKClAuUEkgPC0gbWVyZ2UoUEkxLCBQSTIsIGJ5ID0gIklEIiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9HYXdyb25za2kvIikpCkdhdzEgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUERHYXdyb25za2kxLmNzdiIpCkdhdzIgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUERHYXdyb25za2kyLmNzdiIpCgpjb2xuYW1lcyhHYXcxKVsyOm5jb2woR2F3MSldPC1wYXN0ZShjb2xuYW1lcyhHYXcxWzI6bmNvbChHYXcxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoR2F3MilbMjpuY29sKEdhdzIpXTwtcGFzdGUoY29sbmFtZXMoR2F3MlsyOm5jb2woR2F3MildKSwiVDIiLHNlcD0iXyIpCgpQLkdhdyA8LSBtZXJnZShHYXcxLCBHYXcyLCBieSA9ICJjb2RlIiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9Gb3JzY2hlci8iKSkKRm9yMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzRm9yc2NoZXJQRDEuY3N2IiwgaGVhZGVyID0gVCkKRm9yMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzRm9yc2NoZXJQRDIuY3N2IiwgaGVhZGVyID0gVCkKCmNvbG5hbWVzKEZvcjEpWzI6bmNvbChGb3IxKV08LXBhc3RlKGNvbG5hbWVzKEZvcjFbMjpuY29sKEZvcjEpXSksIlQxIixzZXA9Il8iKQpjb2xuYW1lcyhGb3IyKVsyOm5jb2woRm9yMildPC1wYXN0ZShjb2xuYW1lcyhGb3IyWzI6bmNvbChGb3IyKV0pLCJUMiIsc2VwPSJfIikKClAuRm9yIDwtIG1lcmdlKEZvcjEsIEZvcjIsIGJ5ID0gInN1YmplY3QiLCBhbGwueCA9IFQsIGFsbC55ID0gVCkKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0xhaTEvIikpCkxhaTExPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTFQRDEuY3N2IiwgaGVhZGVyID0gVCkKTGFpMTI8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0xhaVN0dWR5MVBEMi5jc3YiLCBoZWFkZXIgPSBUKQoKY29sbmFtZXMoTGFpMTEpWzI6bmNvbChMYWkxMSldPC1wYXN0ZShjb2xuYW1lcyhMYWkxMVsyOm5jb2woTGFpMTEpXSksIlQxIixzZXA9Il8iKQpjb2xuYW1lcyhMYWkxMilbMjpuY29sKExhaTEyKV08LXBhc3RlKGNvbG5hbWVzKExhaTEyWzI6bmNvbChMYWkxMildKSwiVDIiLHNlcD0iXyIpCgpQLkxhaTEgPC0gbWVyZ2UoTGFpMTEsIExhaTEyLCBieSA9ICJzZXNzaW9uX2lkIiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9MYWkyLyIpKQpMYWkyMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkyUEQxLmNzdiIsIGhlYWRlciA9IFQpCkxhaTIyPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTJQRDIuY3N2IiwgaGVhZGVyID0gVCkKCmNvbG5hbWVzKExhaTIxKVsyOm5jb2woTGFpMjEpXTwtcGFzdGUoY29sbmFtZXMoTGFpMjFbMjpuY29sKExhaTIxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoTGFpMjIpWzI6bmNvbChMYWkyMildPC1wYXN0ZShjb2xuYW1lcyhMYWkyMlsyOm5jb2woTGFpMjIpXSksIlQyIixzZXA9Il8iKQoKUC5MYWkyIDwtIG1lcmdlKExhaTIxLCBMYWkyMiwgYnkgPSAic2Vzc2lvbl9pZCIsIGFsbC54ID0gVCwgYWxsLnkgPSBUKQoKY29sbmFtZXMoUC5DYWwpWzFdIDwtICJzdWJJRCIKUC5DYWwgPC0gY2JpbmQoUC5DYWwsIFN0dWR5ID0gIkNhbGFuY2hpbmkiKQpjb2xuYW1lcyhQLlBJKVsxXSA8LSAic3ViSUQiClAuUEkgPC0gY2JpbmQoUC5QSSwgU3R1ZHkgPSAiUEkiKQpjb2xuYW1lcyhQLkdhdylbMV0gPC0gInN1YklEIgpQLkdhdyA8LSBjYmluZChQLkdhdywgU3R1ZHkgPSAiR2F3cm9uc2tpIikKY29sbmFtZXMoUC5Gb3IpWzFdIDwtICJzdWJJRCIKUC5Gb3IgPC0gY2JpbmQoUC5Gb3IsIFN0dWR5ID0gIkZvcnNjaGVyIikKY29sbmFtZXMoUC5MYWkxKVsxXSA8LSAic3ViSUQiClAuTGFpMSA8LSBjYmluZChQLkxhaTEsIFN0dWR5ID0gIkxhaSAxIikKY29sbmFtZXMoUC5MYWkyKVsxXSA8LSAic3ViSUQiClAuTGFpMiA8LSBjYmluZChQLkxhaTIsIFN0dWR5ID0gIkxhaSAyIikKClBEIDwtIHJiaW5kKFAuQ2FsLFAuUEksUC5HYXcsUC5Gb3IsUC5MYWkxLFAuTGFpMikKClBEJFN0dWR5W1BEJFN0dWR5PT0iUEkiXTwtIlByb2plY3QgSW1wbGljaXQsIDIwMjAiClBEJFN0dWR5W1BEJFN0dWR5PT0iQ2FsYW5jaGluaSJdPC0iV2lsc29uICYgQ2FsYW5jaGluaSwgMjAyMiIKUEQkU3R1ZHlbUEQkU3R1ZHk9PSJMYWkgMSJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMSkgICIKUEQkU3R1ZHlbUEQkU3R1ZHk9PSJMYWkgMiJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMikgICIKUEQkU3R1ZHlbUEQkU3R1ZHk9PSJHYXdyb25za2kiXTwtIkdhd3JvbnNraSBldCBhbC4sIDIwMTciClBEJFN0dWR5W1BEJFN0dWR5PT0iRm9yc2NoZXIiXTwtIkZvcnNjaGVyIGV0IGFsLiwgMjAxNyIKYGBgCgojIFF1YWQgTW9kZWwKCiMjIEFzc29jaWF0ZSBCbGFjay1CYWQKCmBgYHtyfQpBQ2JiU2NhdHRlciA8LSBnZ3Bsb3QoUXVhZCwgYWVzKHg9QUNiYjFfVDEsIHk9QUNiYjFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJBc3NvY2lhdGlvbiBCbGFjay1CYWQiLAogICAgICAgeD0iVGltZSAxIiwgeSA9ICJUaW1lIDIiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkgCkFDYmJTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBQ2JiU2NhdHRlci5qcGciKSxkcGk9NjAwKQpgYGAKCiMjIEFzc29jaWF0ZSBXaGl0ZS1Hb29kCgpgYGB7cn0KQUN3Z1NjYXR0ZXIgPC0gZ2dwbG90KFF1YWQsIGFlcyh4PUFDd2cxX1QxLCB5PUFDd2cxX1QyLCBjb2xvcj1TdHVkeSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iQXNzb2NpYXRpb24gV2hpdGUtR29vZCIsCiAgICAgICB4PSJUaW1lIDEiLCB5ID0gIlRpbWUgMiIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkFDd2dTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBQ3dnU2NhdHRlci5qcGciKSxkcGk9NjAwKQpgYGAKCiMjIERldGVjdGlvbgoKYGBge3J9CkRTY2F0dGVyIDwtIGdncGxvdChRdWFkLCBhZXMoeD1EMV9UMSwgeT1EMV9UMiwgY29sb3I9U3R1ZHkpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkRldGVjdGlvbiIsCiAgICAgICB4PSJUaW1lIDEiLCB5ID0gIlRpbWUgMiIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkRTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJEU2NhdHRlci5qcGciKSxkcGk9NjAwKQpgYGAKCiMjIE92ZXJjb21pbmcgQmlhcwoKYGBge3J9Ck9CU2NhdHRlciA8LSBnZ3Bsb3QoUXVhZCwgYWVzKHg9T0IxX1QxLCB5PU9CMV9UMiwgY29sb3I9U3R1ZHkpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9Ik92ZXJjb21pbmcgQmlhcyIsCiAgICAgICB4PSJUaW1lIDEiLCB5ID0gIlRpbWUgMiIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOSkpICArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpPQlNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIk9CU2NhdHRlci5qcGciKSxkcGk9NjAwKQpgYGAKCiMjIEd1ZXNzaW5nCgpgYGB7cn0KR1NjYXR0ZXIgPC0gZ2dwbG90KFF1YWQsIGFlcyh4PUcxX1QxLCB5PUcxX1QyLCBjb2xvcj1TdHVkeSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iR3Vlc3NpbmciLAogICAgICAgeD0iVGltZSAxIiwgeSA9ICJUaW1lIDIiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkdTY2F0dGVyLmpwZyIpLGRwaT02MDApCmBgYAoKIyMgUGFuZWwKCmBgYHtyfQpsaWJyYXJ5KGdncHVicikKUXVhZFBhbmVsMSA8LSBnZ2FycmFuZ2UoQUN3Z1NjYXR0ZXIsIEFDYmJTY2F0dGVyLCBEU2NhdHRlciwgT0JTY2F0dGVyLCBHU2NhdHRlciwKICAgICAgICAgIG5jb2wgPSAzLCBucm93ID0gMiwgY29tbW9uLmxlZ2VuZCA9IFQpClF1YWRQYW5lbDEKCnJlcXVpcmUoZ3JpZCkgICAjIGZvciB0aGUgdGV4dEdyb2IoKSBmdW5jdGlvbgoKUXVhZFBhbmVsMiA8LSBnZ2FycmFuZ2UoQUN3Z1NjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyB0aGVtZShsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgQUNiYlNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIERTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLAogICAgICAgICAgICAgICAgICAgICAgICBPQlNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIEdTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLAogICAgICAgICAgbmNvbCA9IDMsIG5yb3cgPSAyLCBjb21tb24ubGVnZW5kID0gVCwgbGFiZWxzID0gTlVMTCwgbGVnZW5kID0gInRvcCIsCiAgICAgICAgICBhbGlnbiA9ICJodiIsIAogICAgICAgICAgICAgICAgICAgIGZvbnQubGFiZWwgPSBsaXN0KHNpemUgPSAxMCwgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBmYW1pbHkgPSBOVUxMLCBwb3NpdGlvbiA9ICJ0b3AiKSkKUXVhZFBhbmVsMgoKYW5ub3RhdGVfZmlndXJlKFF1YWRQYW5lbDIsIGxlZnQgPSB0ZXh0R3JvYigiVGltZSAyIiwgcm90ID0gOTAsIHZqdXN0ID0gMSwgZ3AgPSBncGFyKGNleCA9IDEuMykpLAogICAgICAgICAgICAgICAgICAgIGJvdHRvbSA9IHRleHRHcm9iKCJUaW1lIDEiLCB2anVzdCA9IC0uMSwgZ3AgPSBncGFyKGNleCA9IDEuMykpKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiUXVhZFBhbmVsLmpwZyIpLGRwaT02MDApCmBgYAoKCiMgUEQgTW9kZWwKCiMjIEF1dG9tYXRpYyBCbGFjawoKYGBge3J9CkFiU2NhdHRlciA8LSBnZ3Bsb3QoUEQsIGFlcyh4PUFiMV9UMSwgeT1BYjFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJBdXRvbWF0aWMgQmxhY2siLAogICAgICAgeD0iVGltZSAxIiwgeSA9ICJUaW1lIDIiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQWJTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBYlNjYXR0ZXIuanBnIiksZHBpPTYwMCkKYGBgCgojIyBBc3NvY2lhdGUgV2hpdGUKCmBgYHtyfQpBd1NjYXR0ZXIgPC0gZ2dwbG90KFBELCBhZXMoeD1BdzFfVDEsIHk9QXcxX1QyLCBjb2xvcj1TdHVkeSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iQXV0b21hdGljIFdoaXRlIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkF3U2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQXdTY2F0dGVyLmpwZyIpLGRwaT02MDApCmBgYAoKIyMgQ29udHJvbCBHb29kCgpgYGB7cn0KQ3BTY2F0dGVyIDwtIGdncGxvdChQRCwgYWVzKHg9Q3AxX1QxLCB5PUNwMV9UMiwgY29sb3I9U3R1ZHkpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkNvbnRyb2wgR29vZCIsCiAgICAgICB4PSJUaW1lIDEiLCB5ID0gIlRpbWUgMiIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpDcFNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkNwU2NhdHRlci5qcGciKSxkcGk9NjAwKQpgYGAKCiMjIENvbnRyb2wgQmFkCgpgYGB7cn0KQ3VTY2F0dGVyIDwtIGdncGxvdChQRCwgYWVzKHg9Q3UxX1QxLCB5PUN1MV9UMiwgY29sb3I9U3R1ZHkpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkNvbnRyb2wgQmFkIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkN1U2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ3VTY2F0dGVyLmpwZyIpLGRwaT02MDApCmBgYAoKIyMgQ29udHJvbCBXaGl0ZQoKYGBge3J9CkN3U2NhdHRlciA8LSBnZ3Bsb3QoUEQsIGFlcyh4PUN3MV9UMSwgeT1DdzFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJDb250cm9sIFdoaXRlIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkN3U2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ3dTY2F0dGVyLmpwZyIpLGRwaT02MDApCmBgYAoKIyMgQ29udHJvbC1CbGFjawoKYGBge3J9CkNiU2NhdHRlciA8LSBnZ3Bsb3QoUEQsIGFlcyh4PUNiMV9UMSwgeT1DYjFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJDb250cm9sLUJsYWNrIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkNiU2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ2JTY2F0dGVyLmpwZyIpLGRwaT02MDApCmBgYAoKIyMgUGFuZWwKCmBgYHtyfQpsaWJyYXJ5KGdncHVicikKUERQYW5lbDEgPC0gZ2dhcnJhbmdlKEF3U2NhdHRlciwgQWJTY2F0dGVyLCBDdVNjYXR0ZXIsIENwU2NhdHRlciwgQ2JTY2F0dGVyLCBDd1NjYXR0ZXIsCiAgICAgICAgICBuY29sID0gMywgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBUKQpQRFBhbmVsMQoKcmVxdWlyZShncmlkKSAgICMgZm9yIHRoZSB0ZXh0R3JvYigpIGZ1bmN0aW9uCgpQRFBhbmVsMiA8LSBnZ2FycmFuZ2UoQXdTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICArIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksIAogICAgICAgICAgICAgICAgICAgICAgICBBYlNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIEN1U2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgQ3BTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLAogICAgICAgICAgICAgICAgICAgICAgICBDYlNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIEN3U2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgIG5jb2wgPSAzLCBucm93ID0gMiwgY29tbW9uLmxlZ2VuZCA9IFQsIGxhYmVscyA9IE5VTEwsIGxlZ2VuZCA9ICJ0b3AiLAogICAgICAgICAgYWxpZ24gPSAiaHYiLCAKICAgICAgICAgICAgICAgICAgICBmb250LmxhYmVsID0gbGlzdChzaXplID0gMTAsIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgZmFtaWx5ID0gTlVMTCwgcG9zaXRpb24gPSAidG9wIikpClBEUGFuZWwyIDwtIGFubm90YXRlX2ZpZ3VyZShQRFBhbmVsMiwgbGVmdCA9IHRleHRHcm9iKCJUaW1lIDIiLCByb3QgPSA5MCwgdmp1c3QgPSAxLCBncCA9IGdwYXIoY2V4ID0gMS4zKSksCiAgICAgICAgICAgICAgICAgICAgYm90dG9tID0gdGV4dEdyb2IoIlRpbWUgMSIsIHZqdXN0ID0gLS4xLCBncCA9IGdwYXIoY2V4ID0gMS4zKSkpClBEUGFuZWwyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJQRFBhbmVsLmpwZyIpLGRwaT02MDApCmBgYAoKIyBSZWxpYWJpbGl0eSBNZXRhLUFuYWx5c2lzCgpgYGB7cn0KZHQgPC0gcmVhZC5jc3YoIn4vRG9jdW1lbnRzL0dpdEh1Yi9NUFQtUmVsaWFiaWxpdHkvUmV0ZXN0L291dHB1dC9jb21iUXVhZF9EZi5jc3YiKVsyOjZdCgpkdCRQYXJhbVtkdCRQYXJhbT09IkQiXTwtIkRldGVjdGlvbiIKZHQkUGFyYW1bZHQkUGFyYW09PSJPQiJdPC0iT3ZlcmNvbWluZyBCaWFzIgpkdCRQYXJhbVtkdCRQYXJhbT09IkFDYmIiXTwtIkFjdGl2YXRpb24gQmxhY2stQmFkIgpkdCRQYXJhbVtkdCRQYXJhbT09IkFDd2ciXTwtIkFjdGl2YXRpb24gV2hpdGUtR29vZCIKZHQkUGFyYW1bZHQkUGFyYW09PSJHIl08LSJHdWVzc2luZyIKCmR0JFBhcmFtW2R0JFBhcmFtPT0iUEkiXTwtIlByb2plY3QgSW1wbGljaXQsIDIwMjAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ2FsYW5jaGluaSJdPC0iV2lsc29uICYgQ2FsYW5jaGluaSwgMjAyMiIKZHQkUGFyYW1bZHQkUGFyYW09PSJMYWkxIl08LSJMYWkgZXQgYWwuLCAyMDE2IChTdHVkeSAxKSAgIgpkdCRQYXJhbVtkdCRQYXJhbT09IkxhaTIiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDIpICAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iR2F3cm9uc2tpIl08LSJHYXdyb25za2kgZXQgYWwuLCAyMDE3IgpkdCRQYXJhbVtkdCRQYXJhbT09IkZvcnNjaGVyIl08LSJGb3JzY2hlciBldCBhbC4sIDIwMTciCgojIGluZGVudCB0aGUgc3ViZ3JvdXAgaWYgdGhlcmUgaXMgYSBudW1iZXIgaW4gdGhlIHBsYWNlYm8gY29sdW1uCmR0JFBhcmFtIDwtIGlmZWxzZShkdCR0eXBlPT0wLCAKICAgICAgICAgICAgICAgICAgICAgIGR0JFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCIgIiwgZHQkUGFyYW0pKQoKY29sbmFtZXMoZHQpW2NvbG5hbWVzKGR0KT09IlBhcmFtIl0gPC0gIiAgICIKZHQkYCBgIDwtIHBhc3RlKHJlcCgiICIsIDIwKSwgY29sbGFwc2UgPSAiICIpCmR0JGBJQ0MgKDk1JSBDSSlgIDwtIGlmZWxzZShpcy5uYShkdCRJQ0MpLCAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCIlLjJmIFslLjJmLCAlLjJmXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdCRJQ0MsIGR0JENJLkxCLCBkdCRDSS5VQikpCmR0PC1kdFtjKDE6NCw2OjcpXQpjb2xuYW1lcyhkdClbY29sbmFtZXMoZHQpPT0iSUNDICg5NSUgQ0kpIl0gPC0gIiAgICAgIgoKbGlicmFyeShmb3Jlc3RwbG90ZXIpCnAgPC0gZm9yZXN0KAogIGR0W2MoMSw1LDYpXSwKICAgICAgICAgICAgZXN0ID0gZHQkSUNDLAogICAgICAgICAgICBsb3dlciA9IGR0JENJLkxCLCAKICAgICAgICAgICAgdXBwZXIgPSBkdCRDSS5VQiwKICAgICAgICAgICAgY2lfY29sdW1uID0gMiwKICAgICAgICAgICAgcmVmX2xpbmUgPSAuNCwKICAgICAgICAgICAgeGxpbSA9IGMoLS4xLCAxKSwKICAgICAgICAgICAgdGlja3NfYXQgPSBjKDAsIC40LC42LCAuNzUsIDEpLAogIHNpemVzID0gLjEKKQoKbGlicmFyeShncmlkKQpwIDwtIGVkaXRfcGxvdChwLAogICAgICAgICAgICAgICByb3cgPSBzZXEoZnJvbT0xLHRvPW5yb3coZHQpLGJ5PTcpLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZm9udGZhY2UgPSBjKCJib2xkIiwiaXRhbGljIikKICAgICAgICAgICAgICAgICAgICAgICAgICksIGNvbCA9IDEpCgpzdHVkeUluZHMgPC0gc2V0ZGlmZigxOm5yb3coZHQpLHNlcShmcm9tPTEsdG89bnJvdyhkdCksYnk9NykpCnBhcmFtSW5kcyA8LSBzZXEoZnJvbT0xLHRvPW5yb3coZHQpLGJ5PTcpCgpwIDwtIGVkaXRfcGxvdChwLCByb3cgPSBzdHVkeUluZHMsIHdoaWNoID0gImJhY2tncm91bmQiLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZmlsbCA9ICJ3aGl0ZSIpKQpwIDwtIGVkaXRfcGxvdChwLCByb3cgPSBwYXJhbUluZHMsIHdoaWNoID0gImJhY2tncm91bmQiLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZmlsbCA9ICJncmV5IikpCgpgYGAKCgoKYGBge3J9CnBuZyhwYXN0ZTAoc2F2ZXRvLCJRdWFkX1RSVC5wbmciKSwgdW5pdHM9ImluIiwgd2lkdGg9MTAsIGhlaWdodD0xMCwgcmVzPTMwMCkKcGxvdChwKQpkZXYub2ZmKCkKYGBgCgoKYGBge3J9CiMgZ2dzYXZlIGZ1bmN0aW9uCmdncGxvdDI6Omdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJRdWFkX1RSVC5wbmciKSwKICAgICAgICAgICAgICAgIGRwaSA9IDMwMCwKICAgICAgICAgICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJpbiIsIHBsb3Q9cCkKYGBgCgpgYGB7cn0KZHQgPC0gcmVhZC5jc3YoIn4vRG9jdW1lbnRzL0dpdEh1Yi9NUFQtUmVsaWFiaWxpdHkvUmV0ZXN0L291dHB1dC9jb21iUERfRGYuY3N2IilbMjo2XQoKZHQkUGFyYW1bZHQkUGFyYW09PSJBYiJdPC0iQXV0b21hdGljIEJsYWNrIgpkdCRQYXJhbVtkdCRQYXJhbT09IkF3Il08LSJBdXRvbWF0aWMgV2hpdGUiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ2IiXTwtIkNvbnRyb2wgQmxhY2siCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ3ciXTwtIkNvbnRyb2wgV2hpdGUiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ3UiXTwtIkNvbnRyb2wgQmFkIgpkdCRQYXJhbVtkdCRQYXJhbT09IkNwIl08LSJDb250cm9sIEdvb2QiCgpkdCRQYXJhbVtkdCRQYXJhbT09IlBJIl08LSJQcm9qZWN0IEltcGxpY2l0LCAyMDIwIgpkdCRQYXJhbVtkdCRQYXJhbT09IkNhbGFuY2hpbmkiXTwtIldpbHNvbiAmIENhbGFuY2hpbmksIDIwMjIiCmR0JFBhcmFtW2R0JFBhcmFtPT0iTGFpMSJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMSkgICIKZHQkUGFyYW1bZHQkUGFyYW09PSJMYWkyIl08LSJMYWkgZXQgYWwuLCAyMDE2IChTdHVkeSAyKSAgIgpkdCRQYXJhbVtkdCRQYXJhbT09Ikdhd3JvbnNraSJdPC0iR2F3cm9uc2tpIGV0IGFsLiwgMjAxNyIKZHQkUGFyYW1bZHQkUGFyYW09PSJGb3JzY2hlciJdPC0iRm9yc2NoZXIgZXQgYWwuLCAyMDE3IgoKIyBpbmRlbnQgdGhlIHN1Ymdyb3VwIGlmIHRoZXJlIGlzIGEgbnVtYmVyIGluIHRoZSBwbGFjZWJvIGNvbHVtbgpkdCRQYXJhbSA8LSBpZmVsc2UoZHQkdHlwZT09MCwgCiAgICAgICAgICAgICAgICAgICAgICBkdCRQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgIHBhc3RlMCgiICIsIGR0JFBhcmFtKSkKCmNvbG5hbWVzKGR0KVtjb2xuYW1lcyhkdCk9PSJQYXJhbSJdIDwtICIgICAiCmNvbG5hbWVzKGR0KVtjb2xuYW1lcyhkdCk9PSJQYXJhbSJdIDwtICIgICAiCmR0JGAgYCA8LSBwYXN0ZShyZXAoIiAiLCAyMCksIGNvbGxhcHNlID0gIiAiKQpkdCRgSUNDICg5NSUgQ0kpYCA8LSBpZmVsc2UoaXMubmEoZHQkSUNDKSwgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZigiJS4yZiBbJS4yZiwgJS4yZl0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHQkSUNDLCBkdCRDSS5MQiwgZHQkQ0kuVUIpKQpkdDwtZHRbYygxOjQsNjo3KV0KCmNvbG5hbWVzKGR0KVtjb2xuYW1lcyhkdCk9PSJJQ0MgKDk1JSBDSSkiXSA8LSAiICAgICIKCmxpYnJhcnkoZm9yZXN0cGxvdGVyKQpwIDwtIGZvcmVzdCgKICBkdFtjKDEsNSw2KV0sCiAgICAgICAgICAgIGVzdCA9IGR0JElDQywKICAgICAgICAgICAgbG93ZXIgPSBkdCRDSS5MQiwgCiAgICAgICAgICAgIHVwcGVyID0gZHQkQ0kuVUIsCiAgICAgICAgICAgIGNpX2NvbHVtbiA9IDIsCiAgICAgICAgICAgIHJlZl9saW5lID0gLjQsCiAgICAgICAgICAgIHhsaW0gPSBjKC0uMSwgMSksCiAgICAgICAgICAgIHRpY2tzX2F0ID0gYygwLCAuNCwuNiwgLjc1LCAxKSwKICBzaXplcyA9IC4xCikKCmxpYnJhcnkoZ3JpZCkKcCA8LSBlZGl0X3Bsb3QocCwKICAgICAgICAgICAgICAgcm93ID0gc2VxKGZyb209MSx0bz1ucm93KGR0KSxieT03KSwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZvbnRmYWNlID0gYygiYm9sZCIsIml0YWxpYyIpCiAgICAgICAgICAgICAgICAgICAgICAgICApLCBjb2wgPSAxKQoKc3R1ZHlJbmRzIDwtIHNldGRpZmYoMTpucm93KGR0KSxzZXEoZnJvbT0xLHRvPW5yb3coZHQpLGJ5PTcpKQpwYXJhbUluZHMgPC0gc2VxKGZyb209MSx0bz1ucm93KGR0KSxieT03KQoKcCA8LSBlZGl0X3Bsb3QocCwgcm93ID0gc3R1ZHlJbmRzLCB3aGljaCA9ICJiYWNrZ3JvdW5kIiwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZpbGwgPSAid2hpdGUiKSkKcCA8LSBlZGl0X3Bsb3QocCwgcm93ID0gcGFyYW1JbmRzLCB3aGljaCA9ICJiYWNrZ3JvdW5kIiwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZpbGwgPSAiZ3JleSIpKQoKYGBgCgoKCmBgYHtyfQpwbmcocGFzdGUwKHNhdmV0bywiUERQX1RSVC5wbmciKSwgdW5pdHM9ImluIiwgd2lkdGg9MTAsIGhlaWdodD0xMiwgcmVzPTMwMCkKcGxvdChwKQpkZXYub2ZmKCkKYGBgCgpgYGB7cn0KIyBnZ3NhdmUgZnVuY3Rpb24KZ2dwbG90Mjo6Z2dzYXZlKHBhc3RlMChzYXZldG8sIlBEUF9UUlQucG5nIiksCiAgICAgICAgICAgICAgICBkcGkgPSAzMDAsCiAgICAgICAgICAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSAxMiwgdW5pdHMgPSAiaW4iLCBwbG90PXApCmBgYAoKCiMgUmVjb3ZlcnkKCmBgYHtyfQpzZXR3ZChwYXN0ZTAoIi9Wb2x1bWVzL1Jlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9SZWNvdmVyeS9SZWNvdmVyZWRQYXJhbXMvUEQvIikpCnRpbWVzPC1jKCJUaW1lMSIsIlRpbWUyIikKCmFsbHJlY292cyA8LSBhcy5kYXRhLmZyYW1lKG1hdHJpeChuY29sPTE0LG5yb3c9MCkpCgpQRGRpcnMgPC0gbGlzdC5kaXJzKHBhdGggPSAiLiIsIGZ1bGwubmFtZXMgPSBUUlVFLCByZWN1cnNpdmUgPSBUUlVFKVstMV0KZm9yKGQgaW4gUERkaXJzKXsKICBmb3IodGkgaW4gdGltZXMpewogICAgY3VyRmlsZXMgPC0gbGlzdC5maWxlcyhwYXRoPWQscGF0dGVybj0iXFwuY3N2JCIpCiAgICBpZDwtZ3JlcCh0aSxjdXJGaWxlcykKICAgIG91dHB1dDwtcmVhZC5jc3YocGFzdGUwKGQsIi8iLGN1ckZpbGVzW2lkXSkpCiAgICBuYW1lPC1nc3ViKCIuLyIsIiIsZCkKICAgIG5hbWU8LWdzdWIoIiAiLCIiLG5hbWUpCiAgICAKICAgIGlmKHRpPT0iVGltZTEiKXsKICAgICAgI2NvbG5hbWVzKG91dHB1dCkgPC0gcGFzdGUoY29sbmFtZXMob3V0cHV0KSwiVDEiLHNlcD0iXyIpCiAgICAgIG91dHB1dCR0aW1lIDwtICJUMSIKICAgIH1lbHNlIGlmKHRpPT0iVGltZTIiKXsKICAgICAgI2NvbG5hbWVzKG91dHB1dCkgPC0gcGFzdGUoY29sbmFtZXMob3V0cHV0KSwiVDIiLHNlcD0iXyIpCiAgICAgIG91dHB1dCR0aW1lIDwtICJUMiIKICAgIH0KICAgIAogICAgYXNzaWduKHBhc3RlMChuYW1lLCIuUEQuUmVjb3YuIix0aSksb3V0cHV0KQogIH0KICBkZiA8LSByYmluZChnZXQocGFzdGUwKG5hbWUsIi5QRC5SZWNvdi5UaW1lMSIpKSxnZXQocGFzdGUwKG5hbWUsIi5QRC5SZWNvdi5UaW1lMiIpKSkKICBhc3NpZ24ocGFzdGUwKG5hbWUsIi5QRC5SZWNvdiIpLGRmKQogIGFsbHJlY292cyA8LSByYmluZChhbGxyZWNvdnMsY2JpbmQoZGYsU3R1ZHk9bmFtZSkpCn0KCgphbGxyZWNvdnMkU3R1ZHkgPC0gZ3N1YigiTGFpMSIsICJMYWkgMSIsIGFsbHJlY292cyRTdHVkeSkKYWxscmVjb3ZzJFN0dWR5IDwtIGdzdWIoIkxhaTIiLCAiTGFpIDIiLCBhbGxyZWNvdnMkU3R1ZHkpClBELnJlY292cyA8LSBhbGxyZWNvdnMKUEQucmVjb3ZzIDwtIGRwbHlyOjpyZW5hbWUoUEQucmVjb3ZzLCBzdWJJRD1YKQoKdGFwcGx5KFBELnJlY292cyRBYjEsIFBELnJlY292cyRTdHVkeSwgZnVuY3Rpb24oeCkgbGVuZ3RoKHgpKQpgYGAKCmBgYHtyfQpwYXRoIDwtICIvVm9sdW1lcy8iCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL1VDUi8iKSkKQ2FsMSA8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1BEVUNSMS5jc3YiLCBoZWFkZXIgPSBUKQpDYWwyIDwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUERVQ1IyLmNzdiIsIGhlYWRlciA9IFQpCgpDYWwxJHRpbWUgPC0gIlQxIgpDYWwyJHRpbWUgPC0gIlQyIgpDYWwxJHN1YklEIDwtIDE6bnJvdyhDYWwxKQpDYWwyJHN1YklEIDwtIDE6bnJvdyhDYWwyKQpQLkNhbCA8LSByYmluZChDYWwxLCBDYWwyKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvUEkvIikpClBJMSA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQcm9qZWN0SW1wbGljaXRQRDEuY3N2IikKUEkyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1Byb2plY3RJbXBsaWNpdFBEMi5jc3YiKQoKUEkxJHRpbWUgPC0gIlQxIgpQSTIkdGltZSA8LSAiVDIiClBJMSRzdWJJRCA8LSAxOm5yb3coUEkxKQpQSTIkc3ViSUQgPC0gMTpucm93KFBJMikKUC5QSSA8LSByYmluZChQSTEsIFBJMikKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0dhd3JvbnNraS8iKSkKR2F3MSA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQREdhd3JvbnNraTEuY3N2IikKR2F3MiA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQREdhd3JvbnNraTIuY3N2IikKCkdhdzEkdGltZSA8LSAiVDEiCkdhdzIkdGltZSA8LSAiVDIiCkdhdzEkc3ViSUQgPC0gMTpucm93KEdhdzEpCkdhdzIkc3ViSUQgPC0gMTpucm93KEdhdzIpClAuR2F3IDwtIHJiaW5kKEdhdzEsIEdhdzIpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9Gb3JzY2hlci8iKSkKRm9yMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzRm9yc2NoZXJQRDEuY3N2IiwgaGVhZGVyID0gVCkKRm9yMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzRm9yc2NoZXJQRDIuY3N2IiwgaGVhZGVyID0gVCkKCkZvcjEkdGltZSA8LSAiVDEiCkZvcjIkdGltZSA8LSAiVDIiCkZvcjEkc3ViSUQgPC0gMTpucm93KEZvcjEpCkZvcjIkc3ViSUQgPC0gMTpucm93KEZvcjIpClAuRm9yIDwtIHJiaW5kKEZvcjEsIEZvcjIpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9MYWkxLyIpKQpMYWkxMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkxUEQxLmNzdiIsIGhlYWRlciA9IFQpCkxhaTEyPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTFQRDIuY3N2IiwgaGVhZGVyID0gVCkKCkxhaTExJHRpbWUgPC0gIlQxIgpMYWkxMiR0aW1lIDwtICJUMiIKTGFpMTEkc3ViSUQgPC0gMTpucm93KExhaTExKQpMYWkxMiRzdWJJRCA8LSAxOm5yb3coTGFpMTIpClAuTGFpMSA8LSByYmluZChMYWkxMSwgTGFpMTIpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9MYWkyLyIpKQpMYWkyMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkyUEQxLmNzdiIsIGhlYWRlciA9IFQpCkxhaTIyPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTJQRDIuY3N2IiwgaGVhZGVyID0gVCkKCkxhaTIxJHRpbWUgPC0gIlQxIgpMYWkyMiR0aW1lIDwtICJUMiIKTGFpMjEkc3ViSUQgPC0gMTpucm93KExhaTIxKQpMYWkyMiRzdWJJRCA8LSAxOm5yb3coTGFpMjIpClAuTGFpMiA8LSByYmluZChMYWkyMSxMYWkyMikKCmNvbG5hbWVzKFAuQ2FsKVsxXSA8LSAic3ViSUQiClAuQ2FsIDwtIGNiaW5kKFAuQ2FsLCBTdHVkeSA9ICJDYWxhbmNoaW5pIikKY29sbmFtZXMoUC5QSSlbMV0gPC0gInN1YklEIgpQLlBJIDwtIGNiaW5kKFAuUEksIFN0dWR5ID0gIlBJIikKY29sbmFtZXMoUC5HYXcpWzFdIDwtICJzdWJJRCIKUC5HYXcgPC0gY2JpbmQoUC5HYXcsIFN0dWR5ID0gIkdhd3JvbnNraSIpCmNvbG5hbWVzKFAuRm9yKVsxXSA8LSAic3ViSUQiClAuRm9yIDwtIGNiaW5kKFAuRm9yLCBTdHVkeSA9ICJGb3JzY2hlciIpCmNvbG5hbWVzKFAuTGFpMSlbMV0gPC0gInN1YklEIgpQLkxhaTEgPC0gY2JpbmQoUC5MYWkxLCBTdHVkeSA9ICJMYWkgMSIpCmNvbG5hbWVzKFAuTGFpMilbMV0gPC0gInN1YklEIgpQLkxhaTIgPC0gY2JpbmQoUC5MYWkyLCBTdHVkeSA9ICJMYWkgMiIpCgpQRC5vcmlnIDwtIHJiaW5kKFAuQ2FsLFAuUEksUC5HYXcsUC5Gb3IsUC5MYWkxLFAuTGFpMikKUEQub3JpZ1sxXSA8LSBOVUxMCmBgYAoKYGBge3J9Cgpjb2xuYW1lcyhQRC5yZWNvdnMpWzI6IChuY29sKFBELnJlY292cyktMikgXSA8LSBwYXN0ZShjb2xuYW1lcyhQRC5yZWNvdnMpWzI6IChuY29sKFBELnJlY292cyktMikgXSwiUiIsc2VwPSJfIikKY29sbmFtZXMoUEQub3JpZylbMTogKG5jb2woUEQub3JpZyktMykgXSA8LSBwYXN0ZShjb2xuYW1lcyhQRC5vcmlnKVsxOiAobmNvbChQRC5vcmlnKS0zKSBdLCJPIixzZXA9Il8iKQpQRC5vcmlnIDwtIFBELm9yaWdbb3JkZXIoUEQub3JpZyRTdHVkeSwgUEQub3JpZyR0aW1lKSxdClBELnJlY292cyA8LSBQRC5yZWNvdnNbb3JkZXIoUEQucmVjb3ZzJFN0dWR5LCBQRC5yZWNvdnMkdGltZSksXQoKI1BELm9yaWcucmVjb3ZzIDwtIGNiaW5kKFBELm9yaWcsUEQucmVjb3ZzKQpQRC5vcmlnLnJlY292cyA8LSBtZXJnZShQRC5vcmlnLCBQRC5yZWNvdnMsIGJ5ID0gYygic3ViSUQiLCJTdHVkeSIsInRpbWUiKSkKClBELm9yaWcucmVjb3ZzJFN0dWR5W1BELm9yaWcucmVjb3ZzJFN0dWR5PT0iUEkiXTwtIlByb2plY3QgSW1wbGljaXQsIDIwMjAiClBELm9yaWcucmVjb3ZzJFN0dWR5W1BELm9yaWcucmVjb3ZzJFN0dWR5PT0iQ2FsYW5jaGluaSJdPC0iV2lsc29uICYgQ2FsYW5jaGluaSwgMjAyMiIKUEQub3JpZy5yZWNvdnMkU3R1ZHlbUEQub3JpZy5yZWNvdnMkU3R1ZHk9PSJMYWkgMSJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMSkgICIKUEQub3JpZy5yZWNvdnMkU3R1ZHlbUEQub3JpZy5yZWNvdnMkU3R1ZHk9PSJMYWkgMiJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMikgICIKUEQub3JpZy5yZWNvdnMkU3R1ZHlbUEQub3JpZy5yZWNvdnMkU3R1ZHk9PSJHYXdyb25za2kiXTwtIkdhd3JvbnNraSBldCBhbC4sIDIwMTciClBELm9yaWcucmVjb3ZzJFN0dWR5W1BELm9yaWcucmVjb3ZzJFN0dWR5PT0iRm9yc2NoZXIiXTwtIkZvcnNjaGVyIGV0IGFsLiwgMjAxNyIKYGBgCgoKIyBSZWNvdmVyeQoKIyMgUEQgTW9kZWwKCiMjIyBBdXRvbWF0aWMgQmxhY2sKCmBgYHtyfQpBYlNjYXR0ZXIgPC0gZ2dwbG90KFBELm9yaWcucmVjb3ZzLCBhZXMoeD1BYjFfTywgeT1BYjFfUiwgY29sb3I9U3R1ZHksIHNoYXBlPXRpbWUpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkF1dG9tYXRpYyBCbGFjayIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkFiU2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQWJTY2F0dGVyUkVDLmpwZyIpLGRwaT02MDApCmBgYAoKIyMjIEF1dG9tYXRpYyBXaGl0ZQoKYGBge3J9CkF3U2NhdHRlciA8LSBnZ3Bsb3QoUEQub3JpZy5yZWNvdnMsIGFlcyh4PUF3MV9PLCB5PUF3MV9SLCBjb2xvcj1TdHVkeSwgc2hhcGU9dGltZSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iQXV0b21hdGljIFdoaXRlIiwKICAgICAgIHg9Ik9yaWdpbmFsIiwgeSA9ICJSZWNvdmVyZWQiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQXdTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBd1NjYXR0ZXJSRUMuanBnIiksZHBpPTYwMCkKYGBgCgojIyMgQ29udHJvbCBHb29kCgpgYGB7cn0KQ3BTY2F0dGVyIDwtIGdncGxvdChQRC5vcmlnLnJlY292cywgYWVzKHg9Q3AxX08sIHk9Q3AxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJDb250cm9sIEdvb2QiLAogICAgICAgeD0iT3JpZ2luYWwiLCB5ID0gIlJlY292ZXJlZCIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpDcFNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkNwU2NhdHRlclJFQy5qcGciKSxkcGk9NjAwKQpgYGAKCiMjIyBDb250cm9sIEJhZAoKYGBge3J9CkN1U2NhdHRlciA8LSBnZ3Bsb3QoUEQub3JpZy5yZWNvdnMsIGFlcyh4PUN1MV9PLCB5PUN1MV9SLCBjb2xvcj1TdHVkeSwgc2hhcGU9dGltZSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iQ29udHJvbCBCYWQiLAogICAgICAgeD0iT3JpZ2luYWwiLCB5ID0gIlJlY292ZXJlZCIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpDdVNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkN1U2NhdHRlclJFQy5qcGciKSxkcGk9NjAwKQpgYGAKCiMjIyBDb250cm9sIFdoaXRlCgpgYGB7cn0KQ3dTY2F0dGVyIDwtIGdncGxvdChQRC5vcmlnLnJlY292cywgYWVzKHg9Q3cxX08sIHk9Q3cxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJDb250cm9sIFdoaXRlIiwKICAgICAgIHg9Ik9yaWdpbmFsIiwgeSA9ICJSZWNvdmVyZWQiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQ3dTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJDd1NjYXR0ZXJSRUMuanBnIiksZHBpPTYwMCkKYGBgCgojIyMgQ29udHJvbC1CbGFjawoKYGBge3J9CkNiU2NhdHRlciA8LSBnZ3Bsb3QoUEQub3JpZy5yZWNvdnMsIGFlcyh4PUNiMV9PLCB5PUNiMV9SLCBjb2xvcj1TdHVkeSwgc2hhcGU9dGltZSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iQ29udHJvbCBCbGFjayIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkNiU2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ2JTY2F0dGVyUkVDLmpwZyIpLGRwaT02MDApCmBgYAoKIyMjIFBhbmVsCgpgYGB7cn0KbGlicmFyeShnZ3B1YnIpClBEUGFuZWwxIDwtIGdnYXJyYW5nZShBd1NjYXR0ZXIsIEFiU2NhdHRlciwgQ3VTY2F0dGVyLCBDcFNjYXR0ZXIsIENiU2NhdHRlciwgQ3dTY2F0dGVyLAogICAgICAgICAgbmNvbCA9IDMsIG5yb3cgPSAyLCBjb21tb24ubGVnZW5kID0gVCkKUERQYW5lbDEKCnJlcXVpcmUoZ3JpZCkgICAjIGZvciB0aGUgdGV4dEdyb2IoKSBmdW5jdGlvbgoKUERQYW5lbDIgPC0gZ2dhcnJhbmdlKEF3U2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksIAogICAgICAgICAgICAgICAgICAgICAgICBBYlNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIEN1U2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgQ3BTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLAogICAgICAgICAgICAgICAgICAgICAgICBDYlNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIEN3U2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgIG5jb2wgPSAzLCBucm93ID0gMiwgY29tbW9uLmxlZ2VuZCA9IFQsIGxhYmVscyA9IE5VTEwsIGxlZ2VuZCA9IGMoInRvcCIsImJvdHRvbSIpLAogICAgICAgICAgYWxpZ24gPSAiaHYiLCAKICAgICAgICAgICAgICAgICAgICBmb250LmxhYmVsID0gbGlzdChzaXplID0gMTAsIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgZmFtaWx5ID0gTlVMTCwgcG9zaXRpb24gPSAidG9wIikpClBEUGFuZWwyIDwtIGFubm90YXRlX2ZpZ3VyZShQRFBhbmVsMiwgbGVmdCA9IHRleHRHcm9iKCJSZWNvdmVyZWQiLCByb3QgPSA5MCwgdmp1c3QgPSAxLCBncCA9IGdwYXIoY2V4ID0gMS4zKSksCiAgICAgICAgICAgICAgICAgICAgYm90dG9tID0gdGV4dEdyb2IoIk9yaWdpbmFsIiwgdmp1c3QgPSAtLjEsIGdwID0gZ3BhcihjZXggPSAxLjMpKSkKUERQYW5lbDIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIlBEUGFuZWxSRUMuanBnIiksZHBpPTYwMCkKYGBgCgojIyBRdWFkIE1vZGVsCgojIFJlY292ZXJ5CgpgYGB7cn0Kc2V0d2QocGFzdGUwKCIvVm9sdW1lcy9SZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvUmVjb3ZlcnkvUmVjb3ZlcmVkUGFyYW1zL1F1YWQvIikpCnRpbWVzPC1jKCJUaW1lMSIsIlRpbWUyIikKCmFsbHJlY292cyA8LSBhcy5kYXRhLmZyYW1lKG1hdHJpeChuY29sPTE0LG5yb3c9MCkpCgpRdWFkZGlycyA8LSBsaXN0LmRpcnMocGF0aCA9ICIuIiwgZnVsbC5uYW1lcyA9IFRSVUUsIHJlY3Vyc2l2ZSA9IFRSVUUpWy0xXQpmb3IoZCBpbiBRdWFkZGlycyl7CiAgZm9yKHRpIGluIHRpbWVzKXsKICAgIGN1ckZpbGVzIDwtIGxpc3QuZmlsZXMocGF0aD1kLHBhdHRlcm49IlxcLmNzdiQiKQogICAgaWQ8LWdyZXAodGksY3VyRmlsZXMpCiAgICBvdXRwdXQ8LXJlYWQuY3N2KHBhc3RlMChkLCIvIixjdXJGaWxlc1tpZF0pKQogICAgbmFtZTwtZ3N1YigiLi8iLCIiLGQpCiAgICBuYW1lPC1nc3ViKCIgIiwiIixuYW1lKQogICAgCiAgICBpZih0aT09IlRpbWUxIil7CiAgICAgICNjb2xuYW1lcyhvdXRwdXQpIDwtIHBhc3RlKGNvbG5hbWVzKG91dHB1dCksIlQxIixzZXA9Il8iKQogICAgICBvdXRwdXQkdGltZSA8LSAiVDEiCiAgICB9ZWxzZSBpZih0aT09IlRpbWUyIil7CiAgICAgICNjb2xuYW1lcyhvdXRwdXQpIDwtIHBhc3RlKGNvbG5hbWVzKG91dHB1dCksIlQyIixzZXA9Il8iKQogICAgICBvdXRwdXQkdGltZSA8LSAiVDIiCiAgICB9CiAgICAKICAgIGFzc2lnbihwYXN0ZTAobmFtZSwiLlF1YWQuUmVjb3YuIix0aSksb3V0cHV0KQogIH0KICBkZiA8LSByYmluZChnZXQocGFzdGUwKG5hbWUsIi5RdWFkLlJlY292LlRpbWUxIikpLGdldChwYXN0ZTAobmFtZSwiLlF1YWQuUmVjb3YuVGltZTIiKSkpCiAgYXNzaWduKHBhc3RlMChuYW1lLCIuUXVhZC5SZWNvdiIpLGRmKQogIGFsbHJlY292cyA8LSByYmluZChhbGxyZWNvdnMsY2JpbmQoZGYsU3R1ZHk9bmFtZSkpCn0KCgphbGxyZWNvdnMkU3R1ZHkgPC0gZ3N1YigiTGFpMSIsICJMYWkgMSIsIGFsbHJlY292cyRTdHVkeSkKYWxscmVjb3ZzJFN0dWR5IDwtIGdzdWIoIkxhaTIiLCAiTGFpIDIiLCBhbGxyZWNvdnMkU3R1ZHkpClF1YWQucmVjb3ZzIDwtIGFsbHJlY292cwpRdWFkLnJlY292cyA8LSBkcGx5cjo6cmVuYW1lKFF1YWQucmVjb3ZzLCBzdWJJRD1YKQoKdGFwcGx5KFF1YWQucmVjb3ZzJEFDYmIxLCBRdWFkLnJlY292cyRTdHVkeSwgZnVuY3Rpb24oeCkgbGVuZ3RoKHgpKQpgYGAKCmBgYHtyfQpwYXRoIDwtICIvVm9sdW1lcy8iCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL1VDUi8iKSkKQ2FsMSA8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRVQ1IxLmNzdiIsIGhlYWRlciA9IFQpCkNhbDIgPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkVUNSMi5jc3YiLCBoZWFkZXIgPSBUKQoKQ2FsMSR0aW1lIDwtICJUMSIKQ2FsMiR0aW1lIDwtICJUMiIKQ2FsMSRzdWJJRCA8LSAxOm5yb3coQ2FsMSkKQ2FsMiRzdWJJRCA8LSAxOm5yb3coQ2FsMikKUC5DYWwgPC0gcmJpbmQoQ2FsMSwgQ2FsMikKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL1BJLyIpKQpQSTEgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZFByb2plY3RJbXBsaWNpdDEuY3N2IikKUEkyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRQcm9qZWN0SW1wbGljaXQyLmNzdiIpCgpQSTEkdGltZSA8LSAiVDEiClBJMiR0aW1lIDwtICJUMiIKUEkxJHN1YklEIDwtIDE6bnJvdyhQSTEpClBJMiRzdWJJRCA8LSAxOm5yb3coUEkyKQpQLlBJIDwtIHJiaW5kKFBJMSwgUEkyKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvR2F3cm9uc2tpLyIpKQpHYXcxIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRHYXdyb25za2kxLmNzdiIpCkdhdzIgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZEdhd3JvbnNraTIuY3N2IikKCkdhdzEkdGltZSA8LSAiVDEiCkdhdzIkdGltZSA8LSAiVDIiCkdhdzEkc3ViSUQgPC0gMTpucm93KEdhdzEpCkdhdzIkc3ViSUQgPC0gMTpucm93KEdhdzIpClAuR2F3IDwtIHJiaW5kKEdhdzEsIEdhdzIpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9Gb3JzY2hlci8iKSkKRm9yMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZEZvcnNjaGVyMS5jc3YiLCBoZWFkZXIgPSBUKQpGb3IyPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkRm9yc2NoZXIyLmNzdiIsIGhlYWRlciA9IFQpCgpGb3IxJHRpbWUgPC0gIlQxIgpGb3IyJHRpbWUgPC0gIlQyIgpGb3IxJHN1YklEIDwtIDE6bnJvdyhGb3IxKQpGb3IyJHN1YklEIDwtIDE6bnJvdyhGb3IyKQpQLkZvciA8LSByYmluZChGb3IxLCBGb3IyKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvTGFpMS8iKSkKTGFpMTE8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0xhaVN0dWR5MVF1YWQxLmNzdiIsIGhlYWRlciA9IFQpCkxhaTEyPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTFRdWFkMi5jc3YiLCBoZWFkZXIgPSBUKQoKTGFpMTEkdGltZSA8LSAiVDEiCkxhaTEyJHRpbWUgPC0gIlQyIgpMYWkxMSRzdWJJRCA8LSAxOm5yb3coTGFpMTEpCkxhaTEyJHN1YklEIDwtIDE6bnJvdyhMYWkxMikKUC5MYWkxIDwtIHJiaW5kKExhaTExLCBMYWkxMikKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0xhaTIvIikpCkxhaTIxPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTJRdWFkMS5jc3YiLCBoZWFkZXIgPSBUKQpMYWkyMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkyUXVhZDIuY3N2IiwgaGVhZGVyID0gVCkKCkxhaTIxJHRpbWUgPC0gIlQxIgpMYWkyMiR0aW1lIDwtICJUMiIKTGFpMjEkc3ViSUQgPC0gMTpucm93KExhaTIxKQpMYWkyMiRzdWJJRCA8LSAxOm5yb3coTGFpMjIpClAuTGFpMiA8LSByYmluZChMYWkyMSxMYWkyMikKCmNvbG5hbWVzKFAuQ2FsKVsxXSA8LSAic3ViSUQiClAuQ2FsIDwtIGNiaW5kKFAuQ2FsLCBTdHVkeSA9ICJDYWxhbmNoaW5pIikKY29sbmFtZXMoUC5QSSlbMV0gPC0gInN1YklEIgpQLlBJIDwtIGNiaW5kKFAuUEksIFN0dWR5ID0gIlBJIikKY29sbmFtZXMoUC5HYXcpWzFdIDwtICJzdWJJRCIKUC5HYXcgPC0gY2JpbmQoUC5HYXcsIFN0dWR5ID0gIkdhd3JvbnNraSIpCmNvbG5hbWVzKFAuRm9yKVsxXSA8LSAic3ViSUQiClAuRm9yIDwtIGNiaW5kKFAuRm9yLCBTdHVkeSA9ICJGb3JzY2hlciIpCmNvbG5hbWVzKFAuTGFpMSlbMV0gPC0gInN1YklEIgpQLkxhaTEgPC0gY2JpbmQoUC5MYWkxLCBTdHVkeSA9ICJMYWkgMSIpCmNvbG5hbWVzKFAuTGFpMilbMV0gPC0gInN1YklEIgpQLkxhaTIgPC0gY2JpbmQoUC5MYWkyLCBTdHVkeSA9ICJMYWkgMiIpCgpRdWFkLm9yaWcgPC0gcmJpbmQoUC5DYWwsUC5QSSxQLkdhdyxQLkZvcixQLkxhaTEsUC5MYWkyKQpRdWFkLm9yaWdbMV0gPC0gTlVMTApgYGAKCmBgYHtyfQpjb2xuYW1lcyhRdWFkLnJlY292cylbMjogKG5jb2woUXVhZC5yZWNvdnMpLTIpIF0gPC0gcGFzdGUoY29sbmFtZXMoUXVhZC5yZWNvdnMpWzI6IChuY29sKFF1YWQucmVjb3ZzKS0yKSBdLCJSIixzZXA9Il8iKQpjb2xuYW1lcyhRdWFkLm9yaWcpWzE6IChuY29sKFF1YWQub3JpZyktMykgXSA8LSBwYXN0ZShjb2xuYW1lcyhRdWFkLm9yaWcpWzE6IChuY29sKFF1YWQub3JpZyktMykgXSwiTyIsc2VwPSJfIikKUXVhZC5vcmlnIDwtIFF1YWQub3JpZ1tvcmRlcihRdWFkLm9yaWckU3R1ZHksIFF1YWQub3JpZyR0aW1lKSxdClF1YWQucmVjb3ZzIDwtIFF1YWQucmVjb3ZzW29yZGVyKFF1YWQucmVjb3ZzJFN0dWR5LCBRdWFkLnJlY292cyR0aW1lKSxdCgojUXVhZC5vcmlnLnJlY292cyA8LSBjYmluZChRdWFkLm9yaWcsUXVhZC5yZWNvdnMpClF1YWQub3JpZy5yZWNvdnMgPC0gbWVyZ2UoUXVhZC5vcmlnLCBRdWFkLnJlY292cywgYnkgPSBjKCJzdWJJRCIsIlN0dWR5IiwidGltZSIpKQoKUXVhZC5vcmlnLnJlY292cyRTdHVkeVtRdWFkLm9yaWcucmVjb3ZzJFN0dWR5PT0iUEkiXTwtIlByb2plY3QgSW1wbGljaXQsIDIwMjAiClF1YWQub3JpZy5yZWNvdnMkU3R1ZHlbUXVhZC5vcmlnLnJlY292cyRTdHVkeT09IkNhbGFuY2hpbmkiXTwtIldpbHNvbiAmIENhbGFuY2hpbmksIDIwMjIiClF1YWQub3JpZy5yZWNvdnMkU3R1ZHlbUXVhZC5vcmlnLnJlY292cyRTdHVkeT09IkxhaSAxIl08LSJMYWkgZXQgYWwuLCAyMDE2IChTdHVkeSAxKSAgIgpRdWFkLm9yaWcucmVjb3ZzJFN0dWR5W1F1YWQub3JpZy5yZWNvdnMkU3R1ZHk9PSJMYWkgMiJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMikgICIKUXVhZC5vcmlnLnJlY292cyRTdHVkeVtRdWFkLm9yaWcucmVjb3ZzJFN0dWR5PT0iR2F3cm9uc2tpIl08LSJHYXdyb25za2kgZXQgYWwuLCAyMDE3IgpRdWFkLm9yaWcucmVjb3ZzJFN0dWR5W1F1YWQub3JpZy5yZWNvdnMkU3R1ZHk9PSJGb3JzY2hlciJdPC0iRm9yc2NoZXIgZXQgYWwuLCAyMDE3IgpgYGAKCiMjIFF1YWQgTW9kZWwKCiMjIyBBc3NvY2lhdGUgQmxhY2stQmFkCgpgYGB7cn0KQUNiYlNjYXR0ZXIgPC0gZ2dwbG90KFF1YWQub3JpZy5yZWNvdnMsIGFlcyh4PUFDYmIxX08sIHk9QUNiYjFfUiwgY29sb3I9U3R1ZHksIHNoYXBlPXRpbWUpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkFzc29jaWF0aW9uIEJsYWNrLUJhZCIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkFDYmJTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBQ2JiU2NhdHRlclJFQy5qcGciKSxkcGk9NjAwKQpgYGAKCiMjIyBBc3NvY2lhdGUgV2hpdGUtR29vZAoKYGBge3J9CkFDd2dTY2F0dGVyIDwtIGdncGxvdChRdWFkLm9yaWcucmVjb3ZzLCBhZXMoeD1BQ3dnMV9PLCB5PUFDd2cxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJBc3NvY2lhdGlvbiBXaGl0ZS1Hb29kIiwKICAgICAgIHg9Ik9yaWdpbmFsIiwgeSA9ICJSZWNvdmVyZWQiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQUN3Z1NjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkFDd2dTY2F0dGVyUkVDLmpwZyIpLGRwaT02MDApCmBgYAoKIyMjIERldGVjdGlvbgoKYGBge3J9CkRTY2F0dGVyIDwtIGdncGxvdChRdWFkLm9yaWcucmVjb3ZzLCBhZXMoeD1EMV9PLCB5PUQxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJEZXRlY3Rpb24iLAogICAgICAgeD0iT3JpZ2luYWwiLCB5ID0gIlJlY292ZXJlZCIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpEU2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiRFNjYXR0ZXJSRUMuanBnIiksZHBpPTYwMCkKYGBgCgojIyMgT3ZlcmNvbWluZyBCaWFzCgpgYGB7cn0KT0JTY2F0dGVyIDwtIGdncGxvdChRdWFkLm9yaWcucmVjb3ZzLCBhZXMoeD1PQjFfTywgeT1PQjFfUiwgY29sb3I9U3R1ZHksIHNoYXBlPXRpbWUpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9Ik92ZXJjb21pbmcgQmlhcyIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCk9CU2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiT0JTY2F0dGVyUkVDLmpwZyIpLGRwaT02MDApCmBgYAoKIyMjIEd1ZXNzaW5nCgpgYGB7cn0KR1NjYXR0ZXIgPC0gZ2dwbG90KFF1YWQub3JpZy5yZWNvdnMsIGFlcyh4PUcxX08sIHk9RzFfUiwgY29sb3I9U3R1ZHksIHNoYXBlPXRpbWUpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9Ikd1ZXNzaW5nIiwKICAgICAgIHg9Ik9yaWdpbmFsIiwgeSA9ICJSZWNvdmVyZWQiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKR1NjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkdTY2F0dGVyLmpwZyIpLGRwaT02MDApCmBgYAoKIyMjIFBhbmVsCgpgYGB7cn0KbGlicmFyeShnZ3B1YnIpClF1YWRQYW5lbDEgPC0gZ2dhcnJhbmdlKEFDd2dTY2F0dGVyLCBBQ2JiU2NhdHRlciwgRFNjYXR0ZXIsIE9CU2NhdHRlciwgR1NjYXR0ZXIsCiAgICAgICAgICBuY29sID0gMywgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBUKQpRdWFkUGFuZWwxCgpyZXF1aXJlKGdyaWQpICAgIyBmb3IgdGhlIHRleHRHcm9iKCkgZnVuY3Rpb24KClF1YWRQYW5lbDIgPC0gZ2dhcnJhbmdlKEFDd2dTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICArIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksIAogICAgICAgICAgICAgICAgICAgICAgICBBQ2JiU2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgRFNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIE9CU2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgR1NjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICBuY29sID0gMywgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsYWJlbHMgPSBOVUxMLCBsZWdlbmQgPSAidG9wIiwKICAgICAgICAgIGFsaWduID0gImh2IiwgCiAgICAgICAgICAgICAgICAgICAgZm9udC5sYWJlbCA9IGxpc3Qoc2l6ZSA9IDEwLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIGZhbWlseSA9IE5VTEwsIHBvc2l0aW9uID0gInRvcCIpKQpRdWFkUGFuZWwyCgphbm5vdGF0ZV9maWd1cmUoUXVhZFBhbmVsMiwgbGVmdCA9IHRleHRHcm9iKCJSZWNvdmVyZWQiLCByb3QgPSA5MCwgdmp1c3QgPSAxLCBncCA9IGdwYXIoY2V4ID0gMS4zKSksCiAgICAgICAgICAgICAgICAgICAgYm90dG9tID0gdGV4dEdyb2IoIk9yaWdpbmFsIiwgdmp1c3QgPSAtLjEsIGdwID0gZ3BhcihjZXggPSAxLjMpKSkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIlF1YWRQYW5lbFJFQy5qcGciKSxkcGk9NjAwKQpgYGAKCiMgUmVjb3ZlcnkgTWV0YS1BbmFseXNpcwoKIyMgUXVhZAoKCmBgYHtyfQpkdCA8LSByZWFkLmNzdigifi9Eb2N1bWVudHMvR2l0SHViL01QVC1SZWxpYWJpbGl0eS9SZWNvdmVyeS9vdXRwdXQvY29tYlF1YWRfUmVjb3ZlcnlfRGYuY3N2IilbMjo3XQpkdCRpZCA8LSB1bmxpc3QobGFwcGx5KDE6NSwgZnVuY3Rpb24oeCkgcmVwKHgsdGltZXM9MTMpKSkKCmR0JFBhcmFtW2R0JFBhcmFtPT0iRCJdPC0iRGV0ZWN0aW9uIgpkdCRQYXJhbVtkdCRQYXJhbT09Ik9CIl08LSJPdmVyY29taW5nIEJpYXMiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQUNiYiJdPC0iQWN0aXZhdGlvbiBCbGFjay1CYWQiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQUN3ZyJdPC0iQWN0aXZhdGlvbiBXaGl0ZS1Hb29kIgpkdCRQYXJhbVtkdCRQYXJhbT09IkciXTwtIkd1ZXNzaW5nIgoKZHQkUGFyYW1bZHQkUGFyYW09PSJQSSJdPC0iUHJvamVjdCBJbXBsaWNpdCwgMjAyMCIKZHQkUGFyYW1bZHQkUGFyYW09PSJDYWxhbmNoaW5pIl08LSJXaWxzb24gJiBDYWxhbmNoaW5pLCAyMDIyIgpkdCRQYXJhbVtkdCRQYXJhbT09IkxhaTEiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDEpICAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iTGFpMiJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMikgICIKZHQkUGFyYW1bZHQkUGFyYW09PSJHYXdyb25za2kiXTwtIkdhd3JvbnNraSBldCBhbC4sIDIwMTciCmR0JFBhcmFtW2R0JFBhcmFtPT0iRm9yc2NoZXIiXTwtIkZvcnNjaGVyIGV0IGFsLiwgMjAxNyIKCiMgaW5kZW50IHRoZSBzdWJncm91cCBpZiB0aGVyZSBpcyBhIG51bWJlciBpbiB0aGUgcGxhY2VibyBjb2x1bW4KZHQkUGFyYW0gPC0gaWZlbHNlKGR0JHR5cGU9PTAsIAogICAgICAgICAgICAgICAgICAgICAgZHQkUGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAoIiAiLCBkdCRQYXJhbSkpCgpkdCRgIGAgPC0gcGFzdGUocmVwKCIgIiwgMjApLCBjb2xsYXBzZSA9ICIgIikKZHQkYFJlY292ZXJ5ICg5NSUgQ0kpYCA8LSBpZmVsc2UoaXMubmEoZHQkUmVjb3YpLCAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCIlLjJmIFslLjJmLCAlLjJmXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdCRSZWNvdiwgZHQkQ0kuTEIsIGR0JENJLlVCKSkKCmR0MiA8LSBwaXZvdF93aWRlcihkdCwgaWRfY29scyA9IGMoIlBhcmFtIiwiaWQiKSwgIG5hbWVzX2Zyb20gPSBjKFRpbWUpLCB2YWx1ZXNfZnJvbSA9IGMoUmVjb3YsQ0kuTEIsQ0kuVUIsYFJlY292ZXJ5ICg5NSUgQ0kpYCkgKQpkdDIkYFJlY292ZXJ5IFs5NSUgQ0ldYCA8LSBpZmVsc2UoIWlzLm5hKGR0MiRgUmVjb3ZlcnkgKDk1JSBDSSlfTWV0YWApLCBwYXN0ZTAoIiAgICAgICAgICAgICAgICAgIixkdDIkYFJlY292ZXJ5ICg5NSUgQ0kpX01ldGFgKSwgcGFzdGUwKCJUMSA6IiwgcGFzdGUwKGR0MiRgUmVjb3ZlcnkgKDk1JSBDSSlfVGltZTFgKSwgIiA7ICIsICJUMjogIiwgcGFzdGUwKGR0MiRgUmVjb3ZlcnkgKDk1JSBDSSlfVGltZTJgKSkpCmR0MiRgIGAgPC0gcGFzdGUocmVwKCIgIiwgMjApLCBjb2xsYXBzZSA9ICIgIikKCgpkdDM8LWR0MiAlPiUgc2VsZWN0KFBhcmFtLFJlY292X01ldGE6MTEsMTUsMTYpCgpjb2xuYW1lcyhkdDMpW2NvbG5hbWVzKGR0Myk9PSJQYXJhbSJdIDwtICIgICAiCmNvbG5hbWVzKGR0MylbY29sbmFtZXMoZHQzKT09IlJlY292ZXJ5IFs5NSUgQ0ldIl0gPC0gIiAgICAiCgpkdDMkc2l6ZV9NZXRhIDwtIGlmZWxzZShpcy5uYShkdDMkUmVjb3ZfTWV0YSksIE5BLCAxLjIpCmR0MyRzaXplX1QxIDwtIGlmZWxzZShpcy5uYShkdDMkUmVjb3ZfVGltZTEpLCBOQSwgLjYpCmR0MyRzaXplX1QyIDwtIGlmZWxzZShpcy5uYShkdDMkUmVjb3ZfVGltZTIpLCBOQSwgLjYpCgojIFNldC11cCB0aGVtZQp0bSA8LSBmb3Jlc3RfdGhlbWUoCiAgICAgICAgICAgICAgICAgICBjaV9wY2ggPSBjKDE1LCAxNiwgMTcpLAogICAgICAgICAgICAgICAgICAgY2lfY29sID0gYygiYmxhY2siLCJyZWQiLCJibHVlIiksCiAgICAgICAgICAgICAgICAgICBjaV9sdHkgPSBjKCAic29saWQiLCAiZGFzaGVkIiwgImRvdHRlZCIpLAogICAgICAgICAgICAgICAgICAjIGZvb3Rub3RlX2NvbCA9ICJibHVlIiwKICAgICAgICAgICAgICAgICAgIGxlZ2VuZF9uYW1lID0gIiAiLAogICAgICAgICAgICAgICAgICBsZWdlbmRfcG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICAgICAgICAgICAgIGxlZ2VuZF92YWx1ZSA9IGMoIk1ldGEtQW5hbHNpcyAiLCAiVGltZSAxICIsICJUaW1lIDIgIikpCgpsaWJyYXJ5KGZvcmVzdHBsb3RlcikKcCA8LSBmb3Jlc3QoCiAgZHQzW2MoMSwxMiwxMSldLAogICAgICAgICAgICBlc3QgPSBsaXN0KGR0MyRSZWNvdl9NZXRhLCBkdDMkUmVjb3ZfVGltZTEsIGR0MyRSZWNvdl9UaW1lMiksCiAgICAgICAgICAgIGxvd2VyID0gbGlzdChkdDMkQ0kuTEJfTWV0YSwgZHQzJENJLkxCX1RpbWUxLCBkdDMkQ0kuTEJfVGltZTIpLCAKICAgICAgICAgICAgdXBwZXIgPSBsaXN0KGR0MyRDSS5VQl9NZXRhLCBkdDMkQ0kuVUJfVGltZTEsIGR0MyRDSS5VQl9UaW1lMiksCiAgICAgICAgICAgIGNpX2NvbHVtbiA9IDIsCiAgICAgICAgICAgIHJlZl9saW5lID0gLjcsCiAgICAgICAgICAgIHhsaW0gPSBjKC0uMSwgMSksCiAgICAgICAgICAgIHRpY2tzX2F0ID0gYygwLCAyLCAuNSwgLjcsIDEpLAogIHNpemVzID0gbGlzdChkdDMkc2l6ZV9NZXRhLCBkdDMkc2l6ZV9UMSwgZHQzJHNpemVfVDIpLAogIHRoZW1lID0gdG0KKQpwbG90KHApCgpsaWJyYXJ5KGdyaWQpCnAgPC0gZWRpdF9wbG90KHAsCiAgICAgICAgICAgICAgIHJvdyA9IHNlcShmcm9tPTEsdG89bnJvdyhkdDMpLGJ5PTcpLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZm9udGZhY2UgPSBjKCJib2xkIiwiaXRhbGljIikKICAgICAgICAgICAgICAgICAgICAgICAgICksIGNvbCA9IDEpCgpzdHVkeUluZHMgPC0gc2V0ZGlmZigxOm5yb3coZHQzKSxzZXEoZnJvbT0xLHRvPW5yb3coZHQzKSxieT03KSkKcGFyYW1JbmRzIDwtIHNlcShmcm9tPTEsdG89bnJvdyhkdCksYnk9NykKCnAgPC0gZWRpdF9wbG90KHAsIHJvdyA9IHN0dWR5SW5kcywgd2hpY2ggPSAiYmFja2dyb3VuZCIsCiAgICAgICAgICAgICAgIGdwID0gZ3BhcihmaWxsID0gIndoaXRlIikpCnAgPC0gZWRpdF9wbG90KHAsIHJvdyA9IHBhcmFtSW5kcywgd2hpY2ggPSAiYmFja2dyb3VuZCIsCiAgICAgICAgICAgICAgIGdwID0gZ3BhcihmaWxsID0gImdyZXkiKSkKCmBgYAoKYGBge3J9CnBuZygifi9EZXNrdG9wL1F1YWRfUmVjb3ZGb3Jlc3QucG5nIiwgdW5pdHM9ImluIiwgd2lkdGg9MTAsIGhlaWdodD0xNSwgcmVzPTMwMCkKcGxvdChwKQpkZXYub2ZmKCkKYGBgCgpgYGB7cn0KIyBnZ3NhdmUgZnVuY3Rpb24KZ2dwbG90Mjo6Z2dzYXZlKHBhc3RlMChzYXZldG8sIlF1YWRfUmVjb3ZGb3Jlc3QucG5nIiksCiAgICAgICAgICAgICAgICBkcGkgPSAzMDAsCiAgICAgICAgICAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSAxNSwgdW5pdHMgPSAiaW4iLCBwbG90PXApCmBgYAoKCmBgYHtyfQpkdCA8LSByZWFkLmNzdigifi9Eb2N1bWVudHMvR2l0SHViL01QVC1SZWxpYWJpbGl0eS9SZWNvdmVyeS9vdXRwdXQvY29tYlBEX1JlY292ZXJ5X0RmLmNzdiIpWzI6N10KZHQkaWQgPC0gdW5saXN0KGxhcHBseSgxOjYsIGZ1bmN0aW9uKHgpIHJlcCh4LHRpbWVzPTEzKSkpCgpkdCRQYXJhbVtkdCRQYXJhbT09IkFiIl08LSJBdXRvbWF0aWMgQmxhY2siCmR0JFBhcmFtW2R0JFBhcmFtPT0iQXciXTwtIkF1dG9tYXRpYyBXaGl0ZSIKZHQkUGFyYW1bZHQkUGFyYW09PSJDYiJdPC0iQ29udHJvbCBCbGFjayIKZHQkUGFyYW1bZHQkUGFyYW09PSJDdyJdPC0iQ29udHJvbCBXaGl0ZSIKZHQkUGFyYW1bZHQkUGFyYW09PSJDdSJdPC0iQ29udHJvbCBCYWQiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ3AiXTwtIkNvbnRyb2wgR29vZCIKCmR0JFBhcmFtW2R0JFBhcmFtPT0iUEkiXTwtIlByb2plY3QgSW1wbGljaXQsIDIwMjAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ2FsYW5jaGluaSJdPC0iV2lsc29uICYgQ2FsYW5jaGluaSwgMjAyMiIKZHQkUGFyYW1bZHQkUGFyYW09PSJMYWkxIl08LSJMYWkgZXQgYWwuLCAyMDE2IChTdHVkeSAxKSAgIgpkdCRQYXJhbVtkdCRQYXJhbT09IkxhaTIiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDIpICAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iR2F3cm9uc2tpIl08LSJHYXdyb25za2kgZXQgYWwuLCAyMDE3IgpkdCRQYXJhbVtkdCRQYXJhbT09IkZvcnNjaGVyIl08LSJGb3JzY2hlciBldCBhbC4sIDIwMTciCgojIGluZGVudCB0aGUgc3ViZ3JvdXAgaWYgdGhlcmUgaXMgYSBudW1iZXIgaW4gdGhlIHBsYWNlYm8gY29sdW1uCmR0JFBhcmFtIDwtIGlmZWxzZShkdCR0eXBlPT0wLCAKICAgICAgICAgICAgICAgICAgICAgIGR0JFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCIgIiwgZHQkUGFyYW0pKQoKZHQkYCBgIDwtIHBhc3RlKHJlcCgiICIsIDIwKSwgY29sbGFwc2UgPSAiICIpCmR0JGBSZWNvdmVyeSAoOTUlIENJKWAgPC0gaWZlbHNlKGlzLm5hKGR0JFJlY292KSwgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZigiJS4yZiBbJS4yZiwgJS4yZl0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHQkUmVjb3YsIGR0JENJLkxCLCBkdCRDSS5VQikpCgpkdDIgPC0gcGl2b3Rfd2lkZXIoZHQsIGlkX2NvbHMgPSBjKCJQYXJhbSIsImlkIiksICBuYW1lc19mcm9tID0gYyhUaW1lKSwgdmFsdWVzX2Zyb20gPSBjKFJlY292LENJLkxCLENJLlVCLGBSZWNvdmVyeSAoOTUlIENJKWApICkKZHQyJGBSZWNvdmVyeSBbOTUlIENJXWAgPC0gaWZlbHNlKCFpcy5uYShkdDIkYFJlY292ZXJ5ICg5NSUgQ0kpX01ldGFgKSwgcGFzdGUwKCIgICAgICAgICAgICAgICAgICIsZHQyJGBSZWNvdmVyeSAoOTUlIENJKV9NZXRhYCksIHBhc3RlMCgiVDEgOiIsIHBhc3RlMChkdDIkYFJlY292ZXJ5ICg5NSUgQ0kpX1RpbWUxYCksICIgOyAiLCAiVDI6ICIsIHBhc3RlMChkdDIkYFJlY292ZXJ5ICg5NSUgQ0kpX1RpbWUyYCkpKQpkdDIkYCBgIDwtIHBhc3RlKHJlcCgiICIsIDIwKSwgY29sbGFwc2UgPSAiICIpCgoKZHQzPC1kdDIgJT4lIHNlbGVjdChQYXJhbSxSZWNvdl9NZXRhOjExLDE1LDE2KQoKY29sbmFtZXMoZHQzKVtjb2xuYW1lcyhkdDMpPT0iUGFyYW0iXSA8LSAiICAgIgpjb2xuYW1lcyhkdDMpW2NvbG5hbWVzKGR0Myk9PSJSZWNvdmVyeSBbOTUlIENJXSJdIDwtICIgICAgIgoKZHQzJHNpemVfTWV0YSA8LSBpZmVsc2UoaXMubmEoZHQzJFJlY292X01ldGEpLCBOQSwgMS4yKQpkdDMkc2l6ZV9UMSA8LSBpZmVsc2UoaXMubmEoZHQzJFJlY292X1RpbWUxKSwgTkEsIC42KQpkdDMkc2l6ZV9UMiA8LSBpZmVsc2UoaXMubmEoZHQzJFJlY292X1RpbWUyKSwgTkEsIC42KQoKIyBTZXQtdXAgdGhlbWUKdG0gPC0gZm9yZXN0X3RoZW1lKAogICAgICAgICAgICAgICAgICAgY2lfcGNoID0gYygxNSwgMTYsIDE3KSwKICAgICAgICAgICAgICAgICAgIGNpX2NvbCA9IGMoImJsYWNrIiwicmVkIiwiYmx1ZSIpLAogICAgICAgICAgICAgICAgICAgY2lfbHR5ID0gYyggInNvbGlkIiwgImRhc2hlZCIsICJkb3R0ZWQiKSwKICAgICAgICAgICAgICAgICAgIyBmb290bm90ZV9jb2wgPSAiYmx1ZSIsCiAgICAgICAgICAgICAgICAgICBsZWdlbmRfbmFtZSA9ICIgIiwKICAgICAgICAgICAgICAgICAgbGVnZW5kX3Bvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgICAgICBsZWdlbmRfdmFsdWUgPSBjKCJNZXRhLUFuYWxzaXMgIiwgIlRpbWUgMSAiLCAiVGltZSAyICIpKQoKbGlicmFyeShmb3Jlc3RwbG90ZXIpCnAgPC0gZm9yZXN0KAogIGR0M1tjKDEsMTIsMTEpXSwKICAgICAgICAgICAgZXN0ID0gbGlzdChkdDMkUmVjb3ZfTWV0YSwgZHQzJFJlY292X1RpbWUxLCBkdDMkUmVjb3ZfVGltZTIpLAogICAgICAgICAgICBsb3dlciA9IGxpc3QoZHQzJENJLkxCX01ldGEsIGR0MyRDSS5MQl9UaW1lMSwgZHQzJENJLkxCX1RpbWUyKSwgCiAgICAgICAgICAgIHVwcGVyID0gbGlzdChkdDMkQ0kuVUJfTWV0YSwgZHQzJENJLlVCX1RpbWUxLCBkdDMkQ0kuVUJfVGltZTIpLAogICAgICAgICAgICBjaV9jb2x1bW4gPSAyLAogICAgICAgICAgICByZWZfbGluZSA9IC43LAogICAgICAgICAgICB4bGltID0gYygtLjEsIDEpLAogICAgICAgICAgICB0aWNrc19hdCA9IGMoMCwgMiwgLjUsIC43LCAxKSwKICBzaXplcyA9IGxpc3QoZHQzJHNpemVfTWV0YSwgZHQzJHNpemVfVDEsIGR0MyRzaXplX1QyKSwKICB0aGVtZSA9IHRtCikKcGxvdChwKQoKbGlicmFyeShncmlkKQpwIDwtIGVkaXRfcGxvdChwLAogICAgICAgICAgICAgICByb3cgPSBzZXEoZnJvbT0xLHRvPW5yb3coZHQzKSxieT03KSwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZvbnRmYWNlID0gYygiYm9sZCIsIml0YWxpYyIpCiAgICAgICAgICAgICAgICAgICAgICAgICApLCBjb2wgPSAxKQoKc3R1ZHlJbmRzIDwtIHNldGRpZmYoMTpucm93KGR0Myksc2VxKGZyb209MSx0bz1ucm93KGR0MyksYnk9NykpCnBhcmFtSW5kcyA8LSBzZXEoZnJvbT0xLHRvPW5yb3coZHQpLGJ5PTcpCgpwIDwtIGVkaXRfcGxvdChwLCByb3cgPSBzdHVkeUluZHMsIHdoaWNoID0gImJhY2tncm91bmQiLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZmlsbCA9ICJ3aGl0ZSIpKQpwIDwtIGVkaXRfcGxvdChwLCByb3cgPSBwYXJhbUluZHMsIHdoaWNoID0gImJhY2tncm91bmQiLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZmlsbCA9ICJncmV5IikpCgpgYGAKCmBgYHtyfQpwbmcoIn4vRGVza3RvcC9QRF9SZWNvdkZvcmVzdC5wbmciLCB1bml0cz0iaW4iLCB3aWR0aD0xMCwgaGVpZ2h0PTE4LCByZXM9MzAwKQpwbG90KHApCmRldi5vZmYoKQpgYGAKCmBgYHtyfQojIGdnc2F2ZSBmdW5jdGlvbgpnZ3Bsb3QyOjpnZ3NhdmUocGFzdGUwKHNhdmV0bywiUERfUmVjb3ZGb3Jlc3QucG5nIiksCiAgICAgICAgICAgICAgICBkcGkgPSAzMDAsCiAgICAgICAgICAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSAxOCwgdW5pdHMgPSAiaW4iLCBwbG90PXApCmBgYA==